Hibernate (Hibernate)에서 Hibernate (Hibernate) 또는 Hibernate (JPA) + HikariCP 연결 풀로 마이그레이션 중이며 일괄 처리에 문제가 있습니다. 끼워 넣다. 큰 목록을 1000에서 527 000 개의 요소로 저장해야합니다.
의존성없이 하나의 엔티티 만 배치하면 (예 : 5000 요소 Category
클래스) 모든 것이 정상입니다. 내가 (그냥에 대한 Category
설정과 Website
를) 아동 및 부모 개체 모두를 저장하려고하면
그러나, 나는 예외를 얻을 : 목록의 크기가 적은 다음hibernate.jdbc.batch_size
때 org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.entities.Category
그러나 을, 모든 것이 괜찮습니다 너무 !!! 두 개체는 모두 부모와 자식으로 올바르게 저장됩니다. 그것은 정말로 이상하게 보인다!
나는 충분히 봤 거든, StackOverflow에서 검색하지만, 특히 내 문제에 대한 해결책을 찾을 수 없습니다. 연결 풀을 Apache DBCP로 대체하려고 시도했거나 전혀 포함하지 않은 경우), 최대 절전 모드 성능 설정이 변경되어 PostgreSQL db가 H2로 바뀌 었습니다. 그러나 결과는 없습니다.
어디에서 오류가있을 수 있습니까?
JPA에서 내가 원하는 것을 할 수 있습니까? 아니면 엔티티를 별도로 저장해야합니까 (첫째, 부모와 자식)? 또 다른 방법은 내 프로그램에서 flush()
과 clear()
을 제외하는 것입니다.하지만 성능이 좋지 않습니다.
도움을 받으시기 바랍니다. 여기에 세부 사항이 있습니다. 그건 내가 엔티티를 저장하기 위해 노력하고있어 방법은 다음과 같습니다JPA : 동시에 하위 및 상위 엔티티를 저장합니다.
@Repository("experimentDao")
@Transactional
public class Dao {
@PersistenceContext
private EntityManager entityManager;
@Value("${spring.jpa.properties.hibernate.jdbc.batch_size}")
private int batchSize;
public <T extends Entity> void bulkSave(Collection<T> entities) {
int i = 0;
for (Entity entity : entities) {
persistOrMerge(entity);
i++;
if (i % batchSize == 0) {
// Flush a batch of inserts and release memory.
entityManager.flush();
entityManager.clear();
}
}
}
private <T extends Entity> void persistOrMerge(T entity) {
if (entity.getId() == null) {
entityManager.persist(entity);
} else {
entityManager.merge(entity);
}
}
}
(예를에서 발견되었다 : http://frightanic.com/software-development/jpa-batch-inserts/). 내가 스택 트레이스 다음 을 받고 있어요 :
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
at com.example.DemoApplication.main(DemoApplication.java:24) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_101]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_101]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) [idea_rt.jar:na]
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.example.entities.Category; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.entities.Category
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:299) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at com.example.Dao$$EnhancerBySpringCGLIB$$79470367.bulkSave(<generated>) ~[classes/:na]
at com.example.DemoApplication.insertWebsites(DemoApplication.java:44) [classes/:na]
at com.example.DemoApplication.run(DemoApplication.java:30) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) [spring-boot-1.4.1.RELEASE.jar:1.4.1.RELEASE]
... 11 common frames omitted
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.entities.Category
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:765) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:758) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:80) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:398) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:162) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:111) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:425) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:249) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final]
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]
at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_101]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_101]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at com.sun.proxy.$Proxy62.persist(Unknown Source) ~[na:na]
at com.example.Dao.persistOrMerge(Dao.java:36) ~[classes/:na]
at com.example.Dao.bulkSave(Dao.java:24) ~[classes/:na]
at com.example.Dao$$FastClassBySpringCGLIB$$2ada4001.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
... 21 common frames omitted
Website
및 Category
기관은 일대일 관계가, Category
부모입니다.
public abstract class Entity {
public abstract Long getId();
}
@javax.persistence.Entity
@Table(name = "websites")
public class Website extends Entity implements Serializable {
@Id
@GeneratedValue(strategy = SEQUENCE)
@Column(name = "website_id")
private Long id;
@Column(name = "url", unique = true)
private String url;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="category_id")
private Category category;
// getters and setters, toString
}
@javax.persistence.Entity
@Table(name = "categories")
public class Category extends Entity implements Serializable {
@Id
@GeneratedValue(strategy = SEQUENCE)
@Column(name = "category_id")
private Long id;
@Column(name = "category_name", unique = true)
private String categoryName;
// getters, setters, toString
}
는 지금은 같은 Category
에 속하는 5000 개 Website
의 저장 싶어요 : 그리고 지속 할 shouln't하는뿐만 아니라, 추상 슈퍼 클래스가 있습니다.
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
private Dao dao;
@Autowired
public void setDao(Dao dao) {
this.dao = dao;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... strings) throws Exception {
insertWebsites();
}
private void insertWebsites() {
List<Website> entities = new ArrayList<>(5000);
Category category = new Category();
category.setCategoryName("my category");
for (int i = 0; i < 5000; i++) {
Website website = new Website();
website.setUrl("http://example.com" + i);
website.setCategory(category);
entities.add(website);
}
dao.bulkSave(entities);
}
}
설정 및 매개 변수 : 여기가 대량 삽입 할 방법 자세한 것에 대해
(application.properties)
spring.datasource.driver-class-name = org.postgresql.Driver
spring.datasource.url = jdbc:postgresql://localhost:5432/spring_web
spring.datasource.username = postgres
spring.datasource.password = postgresql
spring.datasource.type = com.zaxxer.hikari.HikariDataSource
# Hibernate
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.properties.hibernate.max_fetch_depth = 3
spring.jpa.properties.hibernate.jdbc.fetch_size = 30
spring.jpa.properties.hibernate.jdbc.batch_size = 30
spring.jpa.properties.hibernate.order_inserts = true
spring.jpa.properties.hibernate.order_updates = true
spring.jpa.properties.hibernate.cache.use_second_level_cache = false
(pom.xml 파일)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<!--<scope>runtime</scope>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.5.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
미안, I 모든 세부 사항을 주려고했다. 도움이 필요하십니까?
답장을 보내 주셔서 감사합니다. 나는 당신의 지시를 따랐고 모든 것이 좋습니다. 그러나 캐스케이드에 또 하나의 엔티티 '블랙리스트'를 추가하려고하면 '전달 된 분리 된 엔티티'가 다시 발생합니다. 제발, 내 예제 코드를 참조하십시오 pastebin : [link] (http://pastebin.com/Y26xjS7A) – insanecoding