我使用Spring Boot并希望改善性能。我必须在数据库中下载50000字段的文件。使用休眠。我在Batch inserts找到了解决方案。但我不知道如何从crudrepository获取entitymanager
public interface MyRepository extends CrudRepository<OTA, Long>
application.yaml
jdbc.batch_size: 50
order_inserts: true
order_updates: true
cache.use_second_level_cache: true
我创建了MyStorageService并希望保存我的文件:
@Service @Repository @Transactional public class MyStorageService {
private MyRepository myRepository;
private void insertAll(final List<MyFile> file) {
myRepository.save(file.getListLine());
}
private void insert(final List<OTA> ota) {
Session session = (Session) entityManager.getDelegate();
Transaction tx = session.beginTransaction();
for (int i = 0; i < ota.size(); i++) {
session.save(ota.get(i));
if (i % 50 == 0) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();
}
}
如果在MyStorageService中使用
@PersistenceContext
EntityManager entityManager;
我得到了
ERROR [http-nio-18842-exec-1] JpaTransactionManager:提交异常 被回滚异常覆盖java.lang.IllegalStateException: 交易未在 org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) 在 org.springframework.orm.jpa.JpaTransactionManager $ JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)
ERROR [http-nio-18842-exec-1] JpaTransactionManager:提交异常 被回滚异常覆盖java.lang.IllegalStateException: 交易未在 org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) 在 org.springframework.orm.jpa.JpaTransactionManager $ JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)
如果
@Autowired
EntityManager entityManager;
我得到了
错误[http-nio-18842-exec-5] JpaTransactionManager:提交异常 被回滚异常覆盖java.lang.IllegalStateException: 交易未在 org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) 在 org.springframework.orm.jpa.JpaTransactionManager $ JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)
java.lang.IllegalStateException:EntityManager已关闭 org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:97) 在 org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:88) 在 org.hibernate.jpa.spi.AbstractEntityManagerImpl.clear(AbstractEntityManagerImpl.java:1382) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.orm.jpa.ExtendedEntityManagerCreator $ ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) 在com.sun.proxy。$ Proxy91.clear(未知来源)at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:554)
我使用来自crud存储库的基本方法save
,但是想要提高性能并使用insert。请告诉我如何从crudrepository获取entitymanager
感谢
答案 0 :(得分:2)
我不确定您的弹簧配置是如何设置的。希望这可能会有所帮助,在这里你可以:
如果您在上下文xml或@Configuration java文件中设置了org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
的bean,那么您可以通过以下方式获取实体管理器。
假设您按如下方式声明了上述内容:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSourceRefToBeMentioned"/>
<property name="packagesToScan" value="package.to.be.mentioned"/>
<property name="jpaVendorAdapter" ref="hibernateJPAVendorAdapter"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
现在,在您的服务类中,您可以自动装配LocalContainerEntityManagerFactoryBean,如下所示。
@Autowired
LocalContainerEntityManagerFactoryBean entityManagerFactory;
在您希望获得实体管理员访问权限的方法中,您可以执行以下操作:
EntityManager entityManager = entityManagerFactory.getObject().createEntityManager();
在此之后,下面的代码将遵循:
Session session = (Session) entityManager.getDelegate();
Transaction tx = session.beginTransaction();
....
...
tx.commit();
session.close();
但是,请确保在完成整个事务后关闭entityManager,如下所示:
entityManager.close();
希望这有帮助。
答案 1 :(得分:1)
从我的观点来看,存在一些潜在的问题。
所以我建议将问题分开,例如如果你想自己管理事务,删除不必要的注释,如@Service和@Transactional,但是根据你的代码,除非你在每个批处理完成后在for循环中提交,否则没有必要。
答案 2 :(得分:-1)
只需自动装配EntityManager
@Autowired
EntityManager entityManager;