Наследование сущностей: центральная таблица с общими значениями + расширенный родительский объект - PullRequest
1 голос
/ 10 февраля 2012

Моя схема выглядит так:

Schema

Моя таблица NOMINATION содержит общие данные по всем 4 моим номинациям.

У меня есть 4 типа номинаций:

  1. Номинация сотрудника
  2. Номинация команды
  3. Идея Номинации
  4. Номинация успеха

Теперь, как вы можете видеть, я смоделировал только 3 из 4 таблиц, и это потому, что в этой устаревшей модели данных единственные данные, которые нужны для назначения сотрудника, находятся в таблице назначения.

Таким образом, в основном я использовал DiscriminatorColumn в столбце CATEGORY_CODE для различения и сделал 5 сущностей, 4 из которых наследуются от основной Nomination сущности.

Nomination Сущность -> CoworkerNom, TeamNom, IdeaNom, SuccessNom.

У меня два вопроса:

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, но мне просто любопытно, потому что пока мой метод подсчета возвращает только конкретные подсчеты, основанные на DiscriminatorColumn ...

1 Ответ

1 голос
/ 10 февраля 2012

В 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 подклассы.

...