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

发布于 2025-01-04 00:29:01 字数 4472 浏览 5 评论 0原文

我的架构如下所示:

Schema

我的 NOMINATION 表保存我的所有 4 项提名之间的通用数据。

我有 4 种类型的提名:

  1. 同事提名
  2. 团队提名
  3. 想法提名
  4. 成功提名

现在,如您所见,我只有 4 个表中的 3 个进行建模,这是因为在这个遗留数据模型上,同事提名所需的唯一数据位于提名表。

因此,基本上我在 CATEGORY_CODE 列上使用了 DiscriminatorColumn 来区分并创建了 5 个实体,其中 4 个继承自主 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 -> NominationHibernateDAO -> 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 但我只是很好奇,因为到目前为止我的 count 方法仅返回基于 DiscriminatorColumn 的特定计数...

My schema looks like this:

Schema

My NOMINATION table holds common data between all 4 of my nominations.

I have 4 types of nominations:

  1. Coworker Nomination
  2. Team Nomination
  3. Idea Nomination
  4. Success Nomination

Now, as you can see I only have 3 of the 4 tables modeled, and that is because on this legacy data model the only data that the Coworker Nomination needs is in the Nomination table.

So basically I used DiscriminatorColumn on column CATEGORY_CODE to discriminate and made 5 entities, 4 which inherit from a main Nomination entity.

Nomination Entity -> CoworkerNom, TeamNom, IdeaNom, SuccessNom.

I have two questions:

1. Why are my specific DAOs not fetching columns from their specific tables?
For example:

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

My findByAll method looks like this:

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

and my DAOs, basically inherit from AbstractHibernateDAO where this method is located. It goes like AbstractHibernateDAO -> NominationHibernateDAO -> IdeaNomHibernateDAO.

I get the following error:

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 is an Idea_Nom column, so I'm guessing its stopping at the common columns from NOMINATION and not fetching the specific columns.

2. How would I be able to obtain a list of all nomination despite their type? Can I run a generic DAO against the Nomination entity by itself? This might be a stupid question as I have mentioned I already have a NominationHibernateDAO but I'm just curious because so far my count method only returns specific counts based on the DiscriminatorColumn...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

能怎样 2025-01-11 00:29:01

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 { ... }         

您应该查看 映射实体

(2) 使用 JPA 如果您对层次结构的根目录的 Nomination 进行查询,像上面一样:

select n from Nomination n

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

In Nomination you have not specified the Inheritance strategy, I think you should use JOINED strategy:

@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 { ... }         

You should look at Mapping Entities

(2) with JPA if you do a query on Nomination the root of the hierachy, like above:

select n from Nomination n

it is a polymorphic query, it loads also Nomination subclasses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文