我如何从 crudrepository 获取 entitymanager

mak*_*son 5 hibernate spring-data spring-boot

我使用 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
Run Code Online (Sandbox Code Playgroud)

我创建了 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();
}
Run Code Online (Sandbox Code Playgroud)

}

如果在 MyStorageService 中使用

@PersistenceContext
EntityManager entityManager;
Run Code Online (Sandbox Code Playgroud)

我得到

错误 [http-nio-18842-exec-1] JpaTransactionManager:提交异常被回滚异常 java.lang.IllegalStateException 覆盖:事务在 org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) at org 不活动.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)

错误 [http-nio-18842-exec-1] JpaTransactionManager:提交异常被回滚异常 java.lang.IllegalStateException 覆盖:事务在 org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) at 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) at org 中未激活.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)

java.lang.IllegalStateException:EntityManager 在 org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:97) at org.hibernate.jpa.internal.EntityManagerImpl.checkOpen(EntityManagerImpl.java:88) at org 处关闭。 hibernate.jpa.spi.AbstractEntityManagerImpl.clear(AbstractEntityManagerImpl.java:1382) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect. invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347) at com.sun .proxy.$Proxy91.clear(Unknown Source) 在 org。springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:554)

我使用save来自 crud 存储库的base 方法,但想提高性能并使用插入。请告诉我如何从 crudrepository 获取 entitymanager。
谢谢

Ure*_*uri 5

我不确定你的弹簧配置是如何设置的。希望这可能会有所帮助,这里是:

如果您在上下文 xml 或 @Configuration java 文件中设置了 bean org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,在这种情况下,您可以通过以下方式获取实体管理器。

假设您将上述声明如下:

<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>
Run Code Online (Sandbox Code Playgroud)

现在,在您的服务类中,您可以自动装配 LocalContainerEntityManagerFactoryBean,如下所示。

@Autowired
LocalContainerEntityManagerFactoryBean entityManagerFactory;
Run Code Online (Sandbox Code Playgroud)

在您的方法中,您想要访问实体管理器,您可以执行以下操作:

EntityManager entityManager = entityManagerFactory.getObject().createEntityManager();
Run Code Online (Sandbox Code Playgroud)

之后,将出现以下代码:

Session session = (Session) entityManager.getDelegate();
Transaction tx = session.beginTransaction();
....
...
tx.commit();
session.close();
Run Code Online (Sandbox Code Playgroud)

但是,请确保在完成整个事务后关闭实体管理器,如下所示:

entityManager.close();
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。