【问题标题】:Single table inheritance strategy (or table per class hierarchy) with Oracle and Hibernate使用 Oracle 和 Hibernate 的单表继承策略(或每个类层次结构中的表)
【发布时间】:2015-08-27 12:10:57
【问题描述】:

我正在使用 JEE6、Oracle 数据库 11g 和 Hibernate。我正在尝试进行以下继承工作:

所以 WikiNotification 和 TodoNotification 扩展了通知。 根据单表继承策略,这三个类在数据库中会有一个和一个唯一的表。

这里是通知:

@Entity
@ForceDiscriminator
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="NOTIFICATION_TYPE")
@Table(name="SMH_NOTIFICATION")
public class Notification extends AbstractPersistentObject{

    /**
     * 
     */
    private static final long serialVersionUID = -2313098389774322743L;

    @ManyToOne
    @JoinColumn(name="RECEIVER_ID", nullable=false)
    private Userprofile receiver;


    @Column(name="CLASSIFICATION",nullable = true, length=30)
    private String classification;

    @Column(name="DESCRIPTION", nullable = true, length=60)
    private String description;

    @Column(name="DEADLINE")
    @Temporal(TemporalType.DATE)
    private Date deadline;

这是维基通知:

//@Entity
@DiscriminatorValue("Wiki")
//@Table(name="SMH_NOTIFICATION")
//@Inheritance(discriminatorValue="Wiki")
public class WikiNotification extends Notification{

    /**
     * 
     */
    private static final long serialVersionUID = 5025643991898983953L;


    //the sender is the user who triggers the notification
    //for example, it can the one who modifies someone else's chapters
    @ManyToOne
    @JoinColumn(name="SENDER_ID", nullable=false)
    private Userprofile sender;

    //"0" if the owner has not accepted yet, "1" if he accepted
    @Column(name="ACCEPTED", length=1, nullable=false)
    private String accepted;

    //the notification type can be "delete", "submit" or "modify"
    @Column(name="NOTIFICATIONTYPE",length=20,nullable=false)
    private String notificationType;

    //mofications, deletions and submissions are related to this article chapter
    @ManyToOne
    @JoinColumn(name="ARTICLECHAPTER",nullable=false)
    private ArticleChapter chapter;

还有 TodoNotification :

//@Entity
@DiscriminatorValue("Todo")
//@Table(name="SMH_NOTIFICATION")
public class TodoNotification extends Notification{

    /**
     * 
     */
    private static final long serialVersionUID = 2482841237595539431L;

    @OneToOne
    @JoinColumn(name="TODO_ID", nullable=false)
    private ToDo todo;

到目前为止不起作用的是:

  • 我创建了一个表“SMH_NOTIFICATION”,但没有看到 鉴别器列“NOTIFICATION_TYPE”,我没有其他列用于 WikiNotification 和 TodoNotification:

  • 当我在类 WikiNotification 和 TodoNotification 中编写 @Entity 时,我在我的数据库中创建了两个表 Wikinotification 和 Todonotification,这不是我所期望的。应该只有一个表“SMH_NOTIFICATION”

我尝试了以下教程,但还没有奏效:

http://www.dineshonjava.com/p/implementing-inheritance-in-hibernate.html#.Vd71ZiXtlHw

https://en.wikibooks.org/wiki/Java_Persistence/Inheritance

http://www.thejavageek.com/2014/05/14/jpa-single-table-inheritance-example/

http://uaihebert.com/jpa-mini-book-first-steps-and-detailed-concepts/13/

http://viralpatel.net/blogs/hibernate-inheritence-table-per-hierarchy-mapping/

编辑:

当我将 Notification 设为 abstract 类并在 WikiNotification 和 TodoNotification 添加 @Entity 时,我在 Eclipse 中得到以下几行:

    INFO  27.08.15 14:45:34.996  org.hibernate.tool.hbm2ddl.DatabaseMetadata@getTableMetadata: table not found: TodoNotification
    INFO  27.08.15 14:45:35.001  org.hibernate.tool.hbm2ddl.DatabaseMetadata@getTableMetadata: table not found: WikiNotification
    INFO  27.08.15 14:45:35.007  org.hibernate.tool.hbm2ddl.DatabaseMetadata@getTableMetadata: table not found: TodoNotification
    INFO  27.08.15 14:45:35.012  org.hibernate.tool.hbm2ddl.DatabaseMetadata@getTableMetadata: table not found: WikiNotification

所以我的数据库中有两个表,WikiNotification 和 TodoNotification,而由于单表继承策略,我只希望有一个表。

    <hibernate-configuration>
 <session-factory>
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.format_sql">false</property>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
        <!--  
        <property name="current_session_context_class">thread</property>
        -->
        <property name="hibernate.hbm2ddl.auto">update</property>

       <!-- 
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.use_sql_comments">true</property>
         -->
 </session-factory>
</hibernate-configuration>

DAO 配置文件:

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory">
        <ref local="sessionFactory" />
    </property>
</bean>

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="hibernateProperties">
        <props>
            <!-- Hibernate dialect can be defined in application context -->
            <prop key="hibernate.dialect">%{smh.hibernate.dialect}</prop>
            <prop key="hibernate.show_sql">false</prop> 
            <prop key="hibernate.hbm2ddl.auto">update</prop> 
            <prop key="hibernate.connection.SetBigStringTryClob">true</prop>
            <prop key="hibernate.jdbc.batch_size">0</prop>
        </props>
    </property>
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
        <list>
            <value>com.smh.core.domain</value>
            <!--
                <value>com.seti.core.domain.entity.task.Task</value>
            -->
        </list>
    </property>
</bean>
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <!-- one of the properties available; the maximum file size in bytes -->
    <property name="maxUploadSize" value="50000000" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor"  


class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

【问题讨论】:

  • 您缺少超类的@DiscriminatorValue
  • 我试过了,不行
  • 您使用的是哪个版本的 Hibernate?

标签: java database oracle hibernate inheritance


【解决方案1】:

通知应该是抽象的。 TodoNotification 和 WikiNotification 应该有 @Entity 注释。

【讨论】:

  • 因为没有找到表所以在数据库中创建,而不是为三个类创建一个表。
  • 你确定你扩展了正确的通知类。很抱歉问这个问题,但您要实现的目标确实没有什么复杂的。
  • 那么可能是因为 AbstractPersistentObject。你能展示它的映射吗?
  • 我会尝试删除它
  • 不,如果没有 AbstractPersistentObject,它就无法工作。我添加了我的 dao 配置文件
【解决方案2】:

你需要做几件事:

  1. 确保根据您的 Oracle 版本,您使用的任何方言都是正确的。
  2. 您需要在所有三个类上添加 @Entity
  3. 您需要将所有类映射到您的 hibermate.cfg 文件中
  4. 您需要从子类中删除 "nullable=false",因为当 Discriminator.Value="Wiki" 时,"TODO_ID" 将为空WikiNotification 成员值将是 Discriminator.Value="Todo"
  5. 尝试一下,不要将 hibernate.hbm2ddl.auto 设置为 update,而是尝试将其设置为“create”,然后检查结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多