Hibernate继承和模式迁移

时间:2015-11-10 06:43:43

标签: java hibernate inheritance

我有一个Java Hibernate项目,我在架构迁移时遇到异常。为了更清楚地理解,已经创建了测试项目:https://Li_Ion@bitbucket.org/Li_Ion/hibernatetest

它由带有生成ID列的 AbstractEntity 组成。所有其他实体都从中继承。

import javax.persistence.*;

@MappedSuperclass
public abstract class AbstractEntity {

    @TableGenerator(
            name="entityGen",
            table="Sequence",
            pkColumnName="SeqName",
            pkColumnValue="SeqValue",
            valueColumnName="SeqCount",
            allocationSize=1)
    @Id
    @GeneratedValue(strategy=GenerationType.TABLE, generator="entityGen")
    private Long id;
}

BaseEntity 包含基本业务逻辑(此测试项目为空)。

import java.io.Serializable;

import javax.persistence.Entity;

@Entity
public class BaseEntity extends AbstractEntity implements Serializable {

    private static final long serialVersionUID = 7986579000111260735L;
}

SubEntity 包含一些额外逻辑,它存储在同一个表中, BaseEntity ,并且出于某些目的,需要来自 LinkedEntity <的链接(外键) /强>

import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.*;

import org.hibernate.annotations.SortNatural;

@Entity
public class SubEntity extends BaseEntity {

    private static final long serialVersionUID = -5385038491074771899L;

    @SortNatural
    @OneToMany(fetch= FetchType.LAZY, mappedBy = "baseEntity", cascade= CascadeType.REMOVE)
    private SortedSet<LinkedEntity> linkedEntities = new TreeSet<>();
}

另一方面, LinkedEntity 还需要链接(外键)到 BaseEntity

import java.io.Serializable;

import javax.persistence.*;

@Entity
public class LinkedEntity extends AbstractEntity implements Serializable {

    private static final long serialVersionUID = -862211573175996002L;

    @ManyToOne(fetch = FetchType.LAZY)
    protected BaseEntity baseEntity;
}

我的 persistence.xml 是:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
    version="2.0">

    <persistence-unit name="hibernate-test">
        <properties>
            <!-- Database connection settings -->
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="jadira.usertype.autoRegisterUserTypes" value="true"/>
            <property name="jadira.usertype.databaseZone" value="jvm"/>
            <property name="jadira.usertype.javaZone"  value="jvm"/>

            <property name="javax.persistence.jdbc.url"
                value="jdbc:postgresql://localhost:5432/hibernatetest?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8" />
            <property name="javax.persistence.jdbc.user" value="test" />
            <property name="javax.persistence.jdbc.password" value="test" />

            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />

            <property name="javax.persistence.validation.mode" value="none" />
        </properties>
    </persistence-unit>
</persistence>

最后, Main 类包含对运行模式迁移的调用:

import javax.persistence.Persistence;

public class Main {

    static public  void main(String args[]) {
        Persistence.createEntityManagerFactory("hibernate-test");
    }
}

然后我运行这个测试项目(在空数据库上),我得到一个例外:

Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: hibernate-test] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:877)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:805)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at org.Main.main(Main.java:8)
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Unable to execute schema management to JDBC target [alter table LinkedEntity add constraint FKcsuu8w377ufaw32jb0s42dgny foreign key (baseEntity_id) references BaseEntity]
    at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:59)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:420)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:409)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:374)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:190)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:60)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:129)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:97)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:481)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:802)
    ... 4 more
Caused by: org.postgresql.util.PSQLException: ERROR: constraint "fkcsuu8w377ufaw32jb0s42dgny" for relation "linkedentity" already exists
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2270)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1998)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:570)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:406)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
    at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:56)
    ... 14 more

我使用PostgreSQL 9.4.5,Java 8和Hibernate 5.0.2。所有其他信息都可以在测试项目中找到:https://Li_Ion@bitbucket.org/Li_Ion/hibernatetest

我做错了什么?提前致谢

抱歉我的英文

0 个答案:

没有答案