集合元素(多对多)表别名不能为空

时间:2014-08-05 13:16:01

标签: java hibernate hibernate-mapping

从hibernate 3.6升级到hibernate 4.3.5时,由于@ElementCollection,我得到了以下异常: -

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory_1': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Collection element (many-to-many) table alias cannot be empty
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:398)
    at com.s.af.persistence.HibernateEntityManagerFactoryBuilder.build(HibernateEntityManagerFactoryBuilder.java:53)
    at com.s.af.persistence.PersistenceServiceImpl.buildEntityManagerFactory(PersistenceServiceImpl.java:218)
    at com.s.af.persistence.PersistenceServiceImpl$EntityManagerFactoryMultitenantHolderCallback.build(PersistenceServiceImpl.java:263)
    at com.s.af.persistence.PersistenceServiceImpl$EntityManagerFactoryMultitenantHolderCallback.build(PersistenceServiceImpl.java:259)
    at com.s.af.multitenant.MultitenantHolder.get(MultitenantHolder.java:54)
    at com.s.af.multitenant.MultitenantHolder.get(MultitenantHolder.java:44)
    at com.s.af.persistence.PersistenceServiceImpl.getEntityManagerFactory(PersistenceServiceImpl.java:227)
    at com.s.af.persistence.MultitenantEntityManagerFactory.getDataSource(MultitenantEntityManagerFactory.java:131)
    at org.springframework.orm.jpa.JpaTransactionManager.afterPropertiesSet(JpaTransactionManager.java:308)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    ... 73 more
Caused by: java.lang.IllegalStateException: Collection element (many-to-many) table alias cannot be empty
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.renderManyToManyJoin(LoadQueryJoinAndFetchProcessor.java:357)
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.renderJoin(LoadQueryJoinAndFetchProcessor.java:154)
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoin(LoadQueryJoinAndFetchProcessor.java:137)
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoins(LoadQueryJoinAndFetchProcessor.java:132)
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoin(LoadQueryJoinAndFetchProcessor.java:138)
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoins(LoadQueryJoinAndFetchProcessor.java:132)
    at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoins(LoadQueryJoinAndFetchProcessor.java:113)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadQueryDetails.generate(AbstractLoadQueryDetails.java:171)
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails.<init>(EntityLoadQueryDetails.java:106)
    at org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory.makeEntityLoadQueryDetails(BatchingLoadQueryDetailsFactory.java:73)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.<init>(AbstractLoadPlanBasedEntityLoader.java:100)
    at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:134)
    at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:55)
    at org.hibernate.loader.entity.plan.EntityLoader$Builder.byUniqueKey(EntityLoader.java:98)
    at org.hibernate.loader.entity.plan.EntityLoader$Builder.byPrimaryKey(EntityLoader.java:94)
    at org.hibernate.loader.entity.plan.AbstractBatchingEntityLoaderBuilder.buildNonBatchingLoader(AbstractBatchingEntityLoaderBuilder.java:47)
    at org.hibernate.loader.entity.BatchingEntityLoaderBuilder.buildLoader(BatchingEntityLoaderBuilder.java:76)
    at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:2506)
    at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:2528)
    at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:4035)
    at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:4017)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:481)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:397)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
    at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:67)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
    ... 45 more    
Caused by: java.lang.IllegalStateException: Collection element (many-to-many) table alias cannot be empty
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.renderManyToManyJoin(LoadQueryJoinAndFetchProcessor.java:357)
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.renderJoin(LoadQueryJoinAndFetchProcessor.java:154)
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoin(LoadQueryJoinAndFetchProcessor.java:137)
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoins(LoadQueryJoinAndFetchProcessor.java:132)
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoin(LoadQueryJoinAndFetchProcessor.java:138)
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoins(LoadQueryJoinAndFetchProcessor.java:132)
        at org.hibernate.loader.plan.exec.internal.LoadQueryJoinAndFetchProcessor.processQuerySpaceJoins(LoadQueryJoinAndFetchProcessor.java:113)
        at org.hibernate.loader.plan.exec.internal.AbstractLoadQueryDetails.generate(AbstractLoadQueryDetails.java:171)
        at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails.<init>(EntityLoadQueryDetails.java:106)
        at org.hibernate.loader.plan.exec.internal.BatchingLoadQueryDetailsFactory.makeEntityLoadQueryDetails(BatchingLoadQueryDetailsFactory.java:73)
        at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.<init>(AbstractLoadPlanBasedEntityLoader.java:100)
        at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:134)
        at org.hibernate.loader.entity.plan.EntityLoader.<init>(EntityLoader.java:55)
        at org.hibernate.loader.entity.plan.EntityLoader$Builder.byUniqueKey(EntityLoader.java:98)
        at org.hibernate.loader.entity.plan.EntityLoader$Builder.byPrimaryKey(EntityLoader.java:94)
        at org.hibernate.loader.entity.plan.AbstractBatchingEntityLoaderBuilder.buildNonBatchingLoader(AbstractBatchingEntityLoaderBuilder.java:47)
        at org.hibernate.loader.entity.BatchingEntityLoaderBuilder.buildLoader(BatchingEntityLoaderBuilder.java:76)
        at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:2506)
        at org.hibernate.persister.entity.AbstractEntityPersister.createEntityLoader(AbstractEntityPersister.java:2528)
        at org.hibernate.persister.entity.AbstractEntityPersister.createLoaders(AbstractEntityPersister.java:4035)
        at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:4017)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:481)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1857)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
        at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:397)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
        at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
        at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:67)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
        ... 45 more


根据jira问题https://hibernate.atlassian.net/browse/HHH-8839,这个问题将在hibernate 4.3.7中修复。暂时还有一些解决方法吗?

我的实体类如下(为简单起见,已删除了一些不必要的部分): -

Entity
@Table(name = "RUN_DATA")
@Access(AccessType.PROPERTY)
public class RunData {

    private Long id;
    private Map<RunData, Boolean> predecessors;
    private String name;

    @Id
    @GenericGenerator(name = "processing-seq-generator",
            strategy = "sequence-identity",
            parameters = @Parameter(name = "sequence", value = "RUN_DATA_RD_ID_SEQ"))
    @GeneratedValue(generator = "processing-seq-generator")
    @Column(name = "RD_ID", nullable = false)
    @Override
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "RD_NAME")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ElementCollection(fetch = FetchType.EAGER)
    @JoinTable(name = "RUN_DEPENDENCIES",
            joinColumns = @JoinColumn(name = "RDP_DEPENDENT_ID"))
    @MapKeyJoinColumn(name = "RDP_DEPENDS_ON_ID")
    @Column(name = "RDP_IGNORE_PREDECESSOR_ERRORS")
    public Map<RunData, Boolean> getPredecessors() {
        return predecessors;
    }

    public void setPredecessors(Map<RunData, Boolean> predecessors) {
        this.predecessors = predecessors;
    }

}

表结构如下: 表 - &GT; RUN_DATA

RD_ID | RD_NAME
  1   | P1
  2   | P2

表格 - &gt; RUN_DEPENDENCIES

RDP_DEPENDENT_ID | RDP_DEPENDS_ON_ID | RDP_IGNORE_PREDECESSOR_ERRORS
2                |  1                | 1

注意: - 更改表格结构对我来说不是一个选项!

1 个答案:

答案 0 :(得分:0)

解决方法是使元素集合关联变得懒惰。

@ElementCollection(fetch = FetchType.LAZY)