3

既存のクラスの 1 つ (クラス A) には と の両方@Entity@MappedSuperclass注釈があり、子クラス (クラス B は A を拡張します) には があり@Entityます。

これは正しくありませんが、hibernate-entitymanager 3.3 では問題なく動作しています。両方のエンティティに独自のテーブルがあり、クラス B のテーブルには、クラス A と同じ列に加えて、独自のプロパティに対応する 1 つの追加列があります。

両方の注釈が許可されていないため、3.6 に移行できるように、何年もの間そこにあったこの間違いを修正しようとしています。(投げorg.hibernate.AnnotationException: An entity cannot be annotated with both @Entity and @MappedSuperclass:ます)

置き換えようとしまし@MappedSuperclass@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)が、プロパティの 1 つが B のセットである別のクラスをロードすると、実行時エラーが発生します。

org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:78) - Unknown column 'A.createdDateTime' in 'order clause'
org.hibernate.exception.SQLGrammarException: could not initialize a collection: [com.acmy.AnotherClassC.classBset#975905b5-d59c-4e53-98dd-30cf39b0c831]

との両方を使用するクラス A を修正し、 と を使用するスムーズな方法は何でしょ@Entity@MappedSuperclassか? 既存のデータを修正するために SQL は必要ですか?@Entity@Inheritance

4

1 に答える 1

3

注釈は削除できますが、と はその@MappedSuperClassままにしておきます。@Entity@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

使用できません@GeneratedValue(strategy = GenerationType.AUTO)が、つまり@GeneratedValue(strategy = GenerationType.TABLE)

アップデート

例 - 私のために働く

ジェネレーターをpackage-infoクラスに登録する

パッケージ情報.java

@GenericGenerator(name = "system-uuid", strategy = "uuid")
package db;

import org.hibernate.annotations.GenericGenerator;

あなたのクラス A ClassA.java

package db;

import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class ClassA implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(generator = "system-uuid")
    private String id;

    private String value;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 67 * hash + Objects.hashCode(this.id);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ClassA other = (ClassA) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "db.ClassA[ id=" + id.toString() + " ]";
    }
}

そして、継承されたクラス B ClassB.java

package db;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("B")
public class ClassB extends ClassA {
    private static final long serialVersionUID = 1L;

    @Override
    public String toString() {
        return "db.ClassB[ id=" + getId() + " ]";
    }
}

最後になりましたが、テスト用のメイン クラス

TestDb.java

package db;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class TestDb {
    EntityManager em;

    public static void main(String[] args) {
        new TestDb().start();
    }

    public void start() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("dbtest");
        em = emf.createEntityManager();
        em.getTransaction().begin();
        ClassA a = new ClassA();
        a.setValue("A");
        em.persist(a);
        a = new ClassA();
        a.setValue("B");
        em.persist(a);
        ClassB b = new ClassB();
        b.setValue("C");
        em.persist(b);
        em.getTransaction().commit();

        em.getTransaction().begin();
        List list = em.createQuery("from " + ClassA.class.getSimpleName() + " c order by c.value").getResultList();
        System.out.println("List " + list);
        em.getTransaction().commit();
    }
}

persistence.xmlは次のようになります。im-memoryデータベースで h2database を使用します

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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">
    <persistence-unit name="dbtest" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>db.ClassA</class>
        <class>db.ClassB</class>
        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:"/>
            <property name="javax.persistence.jdbc.user" value="app"/>
            <!--property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/-->
            <property name="javax.persistence.jdbc.password" value="app"/>
            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>
于 2014-04-15T18:27:26.047 に答える