0

I'm currently implementing a Spring-batch that reads and writes to files BUT also needs to do CRUD operations on a database.

I've tried to simply define an Entity manager in my xml configuration, and use it in my DAO class. However, right after the init, the EntityManager becomes null.

Can anyone help me with this ? (a solution or a link via something usable would be perfect).

My batchContext.xml

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${batch.datasource.driverClassName}"/>
    <property name="url" value="${batch.datasource.url}"/>
    <property name="username" value="${batch.datasource.username}"/>
    <property name="password" value="${batch.datasource.password}"/>
    <property name="testOnBorrow" value="true"/>
    <property name="testOnReturn" value="true"/>
    <property name="testWhileIdle" value="true"/>
    <property name="timeBetweenEvictionRunsMillis" value="1800000"/>
    <property name="numTestsPerEvictionRun" value="3"/>
    <property name="minEvictableIdleTimeMillis" value="1800000"/>
</bean>

<bean id="entityManagerFactory" name="entTransactionMgr" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <!-- <property name="persistenceXmlLocation" value="classpath:/META-INF/spring/persistence.xml" /> -->
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="packagesToScan" value="${jpa.scan.packages}"/>
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
    </property>

    <!-- Custom jpaDialect pour le deuxieme batch:job-repository-->
<property name="jpaDialect">
    <bean class="fr.mma.soecm.batchfacade.util.CustomHibernateJpaDialect" />
</property>
    <property name="jpaProperties">
        <props>
            <!-- multiple props here-->
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- mode="aspectj" -->
<tx:annotation-driven  transaction-manager="transactionManager"/>

<batch:job-repository id="jobRepository" data-source="dataSource" transaction-manager="transactionManager"/>

<!-- Jobs held separatelly -->
<import resource="batchContext-job.xml"/>

My DAO

@Repository("batchJobDao")
@Transactional
public class BatchJobDaoImpl implements BatchJobDao{

@PersistenceContext(unitName="persistenceUnit")
@Autowired
private EntityManager entityManager;

//    @PersistenceContext(unitName="persistenceUnit", type=PersistenceContextType.EXTENDED)
//    public void setEntityManager(EntityManager entityManager) {
//        System.out.println("Setting Entity Manager :" + entityManager);
//        this. entityManager = entityManager;
//    }

@PostConstruct
public void init(){
    if (entityManager == null){
        System.out.println(" Entity Manager is null");
    } else {
        System.out.println(" Entity Manager is not null");
        getAllJobExecutions();
    }
}

private static final String RECHERCHER_JOB_EXECUTION = "Select bje from BatchJobExecution bje";

@SuppressWarnings("unchecked")
@Override
@Transactional("transactionManager")
public List<BatchJobExecution> getAllJobExecutions(){

//      EntityManagerFactory emf=Persistence.createEntityManagerFactory("entTransactionMgr");
//      EntityManager em=emf.createEntityManager();

    Query query = entityManager.createQuery(RECHERCHER_JOB_EXECUTION, BatchJobExecution.class);
    List<BatchJobExecution> executions = (List<BatchJobExecution>) query.getResultList();
    System.out.println("EXES : " + executions);
    return executions;
}
}

There is some code commented out because I've tried multiple aproaches (changing the persistence context type, recovering the entity manager "manually", having a persistence.xml file for the entityManager) without succes.

My output when running the job is (without all the extra lines..):

Entity Manager is not null
EXES : [fr.mma.soecm.batchfacade.domain.BatchJobExecution@10e6c33,...]
[BatchService] - Synchronous job launch
[AbstractStep] - Encountered an error executing the step
Caused by: java.lang.NullPointerException

And the null pointer, on debug, is throws by the EntityManager being null when I call the "createQuery" in my DAO.

Thanks for your help. I'll keep searching on my end.. God Speed!

pegas
  • 111
  • 1
  • 9
  • It cannot be `null` (assuming you have either `` or `` !) spring will throw an exception at startup. It will only be `null` with a wrong configuration (i.e. no annotation processing) or if you are creating instances yourself. – M. Deinum Feb 15 '16 at 10:38
  • I think I figured it out. It's returning null when I'm calling it from the constructor but when I 'hit it' in another method..in my case the "doRead" it works as expected. I'll test with all the CRUD methods and confirm. It seems like everytime I post something over here, I get it fixed 5 minutes after.. :) – pegas Feb 15 '16 at 13:03

1 Answers1

1

As mentioned in the comment above, my aparent problem was due to the fact that I was trying to call the Service or the DAO in the Constructor of the Step.

After moving the Service call in the "doRead()" method, I could perform all CRUD operations with the EntityManager.

Please let me know if anyone has questions about this/and how to make it work otherwise, as I've not found any explanation on the internet, since I've began searching last week.

pegas
  • 111
  • 1
  • 9