实体继承:具有公共值+扩展父实体的中心表

时间:2012-02-10 15:03:21

标签: java hibernate spring hibernate-annotations

我的架构如下所示:

Schema

我的NOMINATION表格包含我所有4项提名之间的公共数据。

我有4种提名类型:

  1. 同事提名
  2. 团队提名
  3. 创意提名
  4. 成功提名
  5. 现在,正如您所看到的,我只对4个表中的3个进行了建模,这是因为在此遗留数据模型中,Coworker提名所需的唯一数据位于提名表中。

    所以基本上我在列DiscriminatorColumn上使用CATEGORY_CODE来区分和制作5个实体,4个实体从主Nomination实体继承。

    Nomination实体 - > CoworkerNomTeamNomIdeaNomSuccessNom

    我有两个问题:

    1。为什么我的特定DAO不从其特定表中获取列? 例如:

    Nomination.java:

    @Entity(name = "Nomination")
    @Table(name = "NOMINATION")
    @DiscriminatorColumn(name="CATEGORY_CODE", discriminatorType = DiscriminatorType.STRING, length = 1)
    
    public class Nomination extends AuditableEntity {
    
        @Id
        @Column(name = "NOM_ID", insertable = true, updatable = true,
                nullable = false)
        @GeneratedValue(strategy = GenerationType.AUTO)
        private int id;
    
        @Transient
        protected NominationType type = null;
    
        //So on
    

    IdeaNom.java:

    @Entity(name = "IdeaNom")
    @Table(name = "IDEA_NOM")
    @DiscriminatorValue("I")
    
    public class IdeaNom extends Nomination {
    
        @Column(name = "PURPOSE_INC", insertable = true, updatable = true,
                nullable = true)
        private Boolean purposeIncrease;
    
        @Column(name = "PURPOSE_SIMPLIFY", insertable = true, updatable = true,
                nullable = true)
        private Boolean purposeSimplify;
    
        //so on
    

    AuditableEntity.java:

    @MappedSuperclass
    public abstract class AuditableEntity {
        /**
         * The user who last updated this object. This object is lazy loaded, so
         * make sure a session is open
         */
        @ManyToOne(cascade = {CascadeType.PERSIST,
                CascadeType.MERGE}, fetch = FetchType.LAZY /*optional = true*/)
        @JoinColumn(name = "UPDATED_BY", referencedColumnName = "EMP_ID",
                nullable = true)
        @Cascade(value = {org.hibernate.annotations.CascadeType.PERSIST,
                org.hibernate.annotations.CascadeType.MERGE,
                org.hibernate.annotations.CascadeType.SAVE_UPDATE})
        private Employee modifiedBy = null;
        /**
         * The last system update timestamp for this entity
         */
        @Column(name = "UPDATED_DATE", nullable = true)
        @Temporal(value = TemporalType.TIMESTAMP)
        private Date modifiedOn = null;
    
        //getters and setters
    

    我的findByAll方法如下所示:

    public List<T> findAll() {
            if (logger.isDebugEnabled()) {
                logger.debug("findAll");
            }
            return currentSession().createCriteria(getPersistentClass()).list();
        }
    

    和我的DAO,基本上都是从这个方法所在的AbstractHibernateDAO继承而来的。它就像AbstractHibernateDAO - &gt; NominationHibernateDAO - &gt; IdeaNomHibernateDAO

    我收到以下错误:

    Caused by: java.sql.SQLException: Invalid column name 'ACTUAL_SITUATION'.
        at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:368)
        at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2820)
        at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2258)
        at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:632)
        at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQLQuery(JtdsStatement.java:477)
        at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:778)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
        at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
        at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
        at org.hibernate.loader.Loader.getResultSet(Loader.java:1953)
        at org.hibernate.loader.Loader.doQuery(Loader.java:802)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
        at org.hibernate.loader.Loader.doList(Loader.java:2533)
        ... 38 more
    

    ACTUAL_SITUATION是一个Idea_Nom列,因此我猜测它停在NOMINATION的公共列,而不是获取特定的列。

    2。尽管他们的类型,我怎么能获得所有提名的清单?我可以单独针对提名实体运行通用DAO吗?这可能是一个愚蠢的问题,因为我已经提到我已经有一个NominationHibernateDAO,但我只是好奇,因为到目前为止,我的计数方法只返回基于DiscriminatorColumn的特定计数......

1 个答案:

答案 0 :(得分:1)

Nomination中你没有指定继承策略,我认为你应该使用JOINED策略:

@Entity(name = "Nomination")
@Table(name = "NOMINATION")
@Inheritance(strategy=InheritanceType.JOINED)
public class Nomination extends AuditableEntity {

   @Id
   @Column(name = "NOM_ID", insertable = true, updatable = true,
        nullable = false)
   @GeneratedValue(strategy = GenerationType.AUTO)
   private int id;

   @Transient
   protected NominationType type = null;

  ...
}

@Entity
@PrimaryKeyJoinColumn(name="NOM_ID")
public class IdeaNom  extends Nomination { ... }         

您应该查看Mapping Entities

(2)使用JPA,如果您对Nomination层次结构的根进行查询,如上所述:

select n from Nomination n

它是一个多态查询,它还加载Nomination个子类。