hibernate与主键的双向关联作为外键

时间:2015-02-23 16:43:44

标签: java hibernate jpa many-to-one

我在JPA关系方面遇到很多问题。我一直在网上搜索,发现很多类似于我的案例,但建议的解决方案对我不起作用。让我向您展示映射Oracle表的java类:

@Entity
@Table(name="CONFIGURATIONS")
public class Configuration implements Serializable {

    @Id
    @Column(name="EAC_ID")
    private int id;

    @OneToMany
    @Cascade({CascadeType.ALL})
    @JoinColumn(name="ACT_EAC_ID", nullable=false)
    private List<Actions> actions;

    ...
}

@Entity
@Table(name="ACTIONS")
public class Actions implements Serializable {

    @Id
    @Column(name="ACT_ID")
    private int id;

    @ManyToOne
    @JoinColumn(name="ACT_EAC_ID", updatable=false, insertable=false)
    private Configuration configuration;

    @OneToMany
    @Cascade({CascadeType.ALL})
    @JoinColumn(name="ECF_ACT_ID", nullable=false)
    private List<Filter> filters;

    ...
}

@Entity
@Table(name="FILTERS")
public class Filter implements Serializable {

    @EmbeddedId
    private FilterPK id = new FilterPK();

    @ManyToOne
    @JoinColumn(name = "ECF_ACT_ID", insertable = false, updatable = false)
    private Actions action = null;

    ...
}

@Embeddable
public class FilterPK implements Serializable {

    @Column(name="ECF_KEY", nullable=false, length=100)
    private String key;

    @Column(name="ECF_ACT_ID", insertable = false, updatable = false)
    private int actionId;

}

事情是,在将新配置存储到数据库中时,应自动存储其所有关联的操作,以及与这些操作关联的过滤器。

目前,配置及其操作会自动存储(不包含过滤器)。这就是我实现这一目标的方式:

public int createConfiguration(Configuration conf) {

    for(Actions act : conf.getActions()) {
        act.setConfiguration(conf);
    }

    em.persist(conf);

    return conf.getId();
}

问题在于,当我添加Filter映射时,我总是遇到这个异常:

ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 21)         MSC000001: Failed to start service jboss.persistenceunit.ame: org.jboss.msc.service.StartException in service jboss.persistenceunit."ame": javax.persistence.PersistenceException: [PersistenceUnit: ame]  Unable to build EntityManagerFactory
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:103)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_71]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_71]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.7.0_71]
at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.0.Final-redhat-1.jar:2.1.0.Final-redhat-1]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit:ame] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:930)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:92)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:200)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.access$600(PersistenceUnitServiceImpl.java:57)
at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:99)
... 4 more
**Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: Filter column: ECF_ACT_ID (should be mapped with insert="false" update="false")**
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:682)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:704)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:726)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:479)
at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1284)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1742)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:920)
... 9 more

有没有人遇到同样的问题?我怎么能解决这个问题?

先谢谢你的帮助!!!

1 个答案:

答案 0 :(得分:1)

您需要将mappedBy添加到OneToMany注释中并删除onetomany侧的连接列(它们已在多个方面定义)。

public class Configuration
...
@OneToMany(mappedBy="configuration")
private List<Actions> actions;

您可能还想删除insertable = false,updateble = false