在我们公司,我们有一个奇怪的数据库模型,无法修改,因为许多系统都可以使用它们。据了解,我们有一个直接的 java 应用程序,它通过 hibernate 连接到数据库并加载数据。我们为每个表都有一个 xml 映射文件。
数据库的奇怪之处在于我们没有任何主键。大多数表都有一个包含多个列的唯一索引。
现在我们要使用应用程序服务器 (jboss) 和 ejb 模型。所以我创建了一个这样的类:
@Entity
@Table (name = "eakopf_t")
public class Eakopf implements Serializable {
@Embeddable
public static class EakopfId implements Serializable {
private String mandant;
private String fk_eakopf_posnr;
// I removed here the getters and setters to shorten it up
}
@Id
private EakopfId id;
private String login;
// I removed the getters and setters here as well
}
这很完美。
因为我们的客户有不同版本的数据库架构,所以我考虑在每个数据库版本更改时扩展此类。所以我们用java创建的每个接口(interface)都可以决定使用哪个版本的表。
这是扩展表类
@Entity
@Table (name = "eakopf_t")
public class Eakopf6001 extends Eakopf implements Serializable {
private String newField;
// getters and setters
}
如果我使用 Eakopf(基本版本),如果我执行类似的操作,它就可以工作:
EakopfId id = new EakopfId();
id.setMandant("001");
id.setFk_eakopf_posnr("ABC");
Eakopf kopf = (Eakopf) em.find(Eakopf.class, id);
但是如果我这样做:
EakopfId id = new EakopfId();
id.setMandant("001");
id.setFk_eakopf_posnr("ABC");
Eakopf6001 kopf = (Eakopf6001) em.find(Eakopf6001.class, id);
发生此异常
javax.ejb.EJBException: javax.persistence.PersistenceException:
org.hibernate.WrongClassException: Object with id:
de.entity.Eakopf$EakopfId@291bfe83 was not of the specified subclass:
de.entity.Eakopf (Discriminator: null)
有人有想法吗?
许多问候, 豪克
最佳答案
执行您所做的操作对于 Hibernate 来说意味着您将两种不同类型的实体存储在一个表中。如果您使用鉴别器列,这是可能的。但如果我理解正确的话,你只想要表中的一种实体:Eakopf6001。在这种情况下,其基类应使用 @MappedSuperClass
进行注释,而不是使用 @Entity
进行注释。
我建议创建一个用 @MappedEntity
注释的类(我们称之为 BaseEakopf)和两个实体:EaKopf 和 EaKopf6001,每个实体都有一组附加字段。在映射类列表中包含其他实体之一,具体取决于您要使用的实体。
我个人的观点是,如果您的应用有多个版本,它们应该使用相同的实体,但具有不同的字段。您的版本控制系统将处理这些多个版本,而不是您的源代码(即应用程序的每个版本都有一组源文件,而不是所有可能版本的一组源文件)。
关于java - 在 hibernate 中使用组合键扩展实体类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7050316/