Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How I can get entitymanager from crudrepository

I use Spring Boot and want to improve perfomance. I must download file with 50000 field in database. Use hibernate. I found solution in Batch inserts. But I don't know how get entitymanager from crudrepository

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

I creatred MyStorageService and want to save my file:

@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();
}

}

If use in MyStorageService

@PersistenceContext
EntityManager entityManager;

I get

ERROR [http-nio-18842-exec-1] JpaTransactionManager: Commit exception overridden by rollback exception java.lang.IllegalStateException: Transaction not active at org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) at org.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)

ERROR [http-nio-18842-exec-1] JpaTransactionManager: Commit exception overridden by rollback exception java.lang.IllegalStateException: Transaction not active at org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) at org.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)

If

@Autowired
EntityManager entityManager;

I get

ERROR [http-nio-18842-exec-5] JpaTransactionManager: Commit exception overridden by rollback exception java.lang.IllegalStateException: Transaction not active at org.hibernate.jpa.internal.TransactionImpl.getRollbackOnly(TransactionImpl.java:131) at org.springframework.orm.jpa.JpaTransactionManager$JpaTransactionObject.isRollbackOnly(JpaTransactionManager.java:665)

java.lang.IllegalStateException: EntityManager is closed at 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.DelegatingMethodAccessorImpl.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) at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:554)

I use base method savefrom crud repository, but want to improve perfomance and use insert. Tell me please how get entitymanager from crudrepository.
Thanks

like image 870
makson Avatar asked Oct 17 '22 11:10

makson


1 Answers

I am not sure of how your spring configuration is set. With a hope this might help, here you go:

If you have set up a bean of org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean in your context xml or @Configuration java file, in that case, you can acquire the entity manager in the following way.

Assume that you declared the above one as follows:

<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>

Now in your service class, you can Autowire the LocalContainerEntityManagerFactoryBean as below.

@Autowired
LocalContainerEntityManagerFactoryBean entityManagerFactory;

In your method, where you want to get access to entity manager, you can do as below:

EntityManager entityManager = entityManagerFactory.getObject().createEntityManager();

After this, the below code would follow:

Session session = (Session) entityManager.getDelegate();
Transaction tx = session.beginTransaction();
....
...
tx.commit();
session.close();

However, make sure you close the entityManager after you are done with the whole transaction, like below:

entityManager.close();

Hope this helps.

like image 189
Uresh K Avatar answered Oct 21 '22 06:10

Uresh K