其中一个现有类(A类)同时具有@Entity
和@MappedSuperclass
注释,而子类(B类扩展为A)具有@Entity
。
虽然这不对,但它与hibernate-entitymanager 3.3一起工作正常。两个实体都有自己的表,B类的表与A类相同,另外一列与其自己的属性对应。
我试图修复这个坐在那里多年的错误,所以我可以迁移到3.6,因为它不允许这两个注释。 (它抛出org.hibernate.AnnotationException: An entity cannot be annotated with both @Entity and @MappedSuperclass:
)
我尝试将@MappedSuperclass
替换为@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
但现在我在加载另一个类时遇到运行时错误,其中一个属性是一组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]
使用@Entity
和@MappedSuperclass
同时使用@Entity
和@Inheritance
修复A类的顺利方法是什么?我是否需要任何SQL来修复现有数据?
答案 0 :(得分:3)
您可以删除@MappedSuperClass
注释 - 但请离开@Entity
和@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
。
您无法使用@GeneratedValue(strategy = GenerationType.AUTO)
,但@GeneratedValue(strategy = GenerationType.TABLE)
<强>更新强>
一个例子 - 适合我
在package-info
班级
<强> 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 如下所示。我将h2database与im-memory
数据库
<?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>