Spring Batch - 具有Hibernate AssertionError的项目处理器

时间:2016-08-02 21:21:10

标签: spring hibernate spring-batch

关于与任务执行器并行化的块处理,我有一个奇怪的问题。 这些项目通过JpaPagingItemReader读取。 有时我在我的ItemProcessor中收到了一个模糊的问题,我绝对不知道为什么: - (

ItemProcessor接收到EntityBeans,它是JpaPagingItemReader( jpavendor:Hibernate )的结果。

   @Override
    public DocumentRequestType process(CmabAuftrag cmabAuftrag) throws Exception {

        LOGGER.info(String.format("start process cmabauftrag %s - working thread %s",
                cmabAuftrag.getAuftragsId(), Thread.currentThread().getId()));

    String docContainer = cmabAuftrag.getArcoOid().getContainer();

最后一个语句产生错误,而不是以一种持续的方式产生错误!

21:43:20 java.lang.AssertionError
21:43:20    at org.hibernate.engine.internal.EntityEntryContext.addEntityEntry(EntityEntryContext.java:125)
21:43:20    at org.hibernate.engine.internal.StatefulPersistenceContext.addEntry(StatefulPersistenceContext.java:505)
21:43:20    at org.hibernate.engine.internal.StatefulPersistenceContext.addEntity(StatefulPersistenceContext.java:462)
21:43:20    at org.hibernate.engine.internal.TwoPhaseLoad.addUninitializedEntity(TwoPhaseLoad.java:360)
21:43:20    at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.loadFromResultSet(EntityReferenceInitializerImpl.java:310)
21:43:20    at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.hydrateEntityState(EntityReferenceInitializerImpl.java:251)
21:43:20    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:107)
21:43:20    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:255)
21:43:20    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:129)
21:43:20    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138)
21:43:20    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102)
21:43:20    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186)
21:43:20    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126)
21:43:20    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:502)
21:43:20    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:467)
21:43:20    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:212)
21:43:20    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:145)
21:43:20    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
21:43:20    at org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:976)
21:43:20    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:173)
21:43:20    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
21:43:20    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
21:43:20    at de.axa.batch.ecmcm.cmab.persistence.domain.CmabArchivContainer_$$_jvst5ca_1.getContainer(CmabArchivContainer_$$_jvst5ca_1.java)
21:43:20    at de.axa.batch.ecmcm.cmab.core.batch.process.MidxRequestItemProcessor.process(MidxRequestItemProcessor.java:80)
21:43:20    at 

从Entity读取容器属性时会发生这种情况,该实体属于父实体 CmabAuftrag

@Entity
@Table(name = "CMAB_AUFTRAG")
@SequenceGenerator(name = "idGenerator", sequenceName = "SEQ_CMAB_AUFTRAG_AUFTRAGS_ID")
public class CmabAuftrag implements Serializable {
...........
    @JoinColumn(name = "ARCO_OID", referencedColumnName = "OID", unique = true, nullable = false)
    @OneToOne(cascade = CascadeType.PERSIST, optional = true, fetch = FetchType.LAZY)
    private CmabArchivContainer arcoOid;

CmabArchivcontainer:

@Entity
@Table(name = "CMAB_ARCHIV_CONTAINER")
@SequenceGenerator(name = "idGenerator", sequenceName = "SEQ_CMAB_ARCHIV_CONTAINER_OID")
public class CmabArchivContainer implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Basic(optional = false)
    @Column(name = "OID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idGenerator")
    private Long oid;
    @Basic(optional = false)
    @Lob
    @Column(name = "CONTAINER")
    private String container;
.....
    public String getContainer() {
        return container;
    }

附上我的作业的块配置(作为提示:在此测试配置案例中,taskExecutor concurrencyLimit设置为2 )。

<bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" scope="step">
    <property name="concurrencyLimit" value="2"/>
</bean>

<batch:job id="processMasterindexJob" job-repository="jobRepository" restartable="false" parent="baseJob">
      <batch:step id="midxStep" parent="stepParent">
             <batch:tasklet transaction-manager="transactionManager" task-executor="taskExecutor">
                    <batch:chunk
                           reader="processMidxDbItemReader"
                           processor="midxItemProcessor"
                           writer="midxCompositeItemWriter"
                           processor-transactional="false"
                           reader-transactional-queue="false"
                           skip-limit="${cmab.batch.skip.limit}"
                           commit-interval="#{jobParameters['toProcess']==T(de.axa.batch.ecmcm.cmab.util.CmabConstants).TYPE_POSTAUSGANG ? '${consumer.global.pa.midx.readCount}' : '${consumer.global.pe.midx.readCount}' }"
                           cache-capacity="20">
                        <batch:skippable-exception-classes>

..................

我完全不知道为什么进程无法接收引用的实体bean CmabArchivContainer的属性。

    String docContainer = cmabAuftrag.getArcoOid().getContainer();

我观察到的是taskExecutor诱导了itemProcess同时被处理。

    21:43:20 2016-08-02 21:43:20,115 INFO   MidxRequestItemProcessor process 52 - start process cmabauftrag 2 - working thread 61
    21:43:20 2016-08-02 21:43:20,115 INFO   MidxRequestItemProcessor process 52 - start process cmabauftrag 3 - working thread 62
    21:43:20 Hibernate: select cmabarchiv0_.OID as OID1_2_0_, cmabarchiv0_.CONTAINER as CONTAINER2_2_0_ from CMAB_ARCHIV_CONTAINER cmabarchiv0_ where cmabarchiv0_.OID=?
    21:43:20 2016-08-02 21:43:20,127 WARN   LogRetryListener onError 36 - ------------------- START RETRY OPERATION
    .......
21:43:20 2016-08-02 21:43:20,129 DEBUG  MidxRequestItemProcessor mapPostausgangsDocToRequestType 104 - map postausgang to midx request for auftragsid 2

重试操作是由AssertionError引起的(见上文),并且取决于cmabAuftrag&lt; 3&gt;。 嗯,这可能是元素&#34;容器&#34;无法阅读&#34;来自并发环境中的第二个实体CmabArchivContainer(cmabAuftrag = 3)?

不幸的是,我真的陷入了困境,并且没有任何线索: - (

任何帮助都将非常感谢!

非常感谢提前和问候,

博多

0 个答案:

没有答案