Java 在hibernate中使用复合键扩展实体类
在我们公司,我们有一个奇怪的数据库模型,无法修改,因为很多系统都使用它。据我们所知,我们有一个直接的java应用程序,它与hibernate连接到数据库并加载数据。每个表都有一个xml映射文件 数据库的奇怪之处在于我们没有任何主键。大多数表都有一个包含多个列的唯一索引 现在我们想要使用应用服务器(jboss)和ejb模型。所以我创建了一个这样的类:Java 在hibernate中使用复合键扩展实体类,java,hibernate,Java,Hibernate,在我们公司,我们有一个奇怪的数据库模型,无法修改,因为很多系统都使用它。据我们所知,我们有一个直接的java应用程序,它与hibernate连接到数据库并加载数据。每个表都有一个xml映射文件 数据库的奇怪之处在于我们没有任何主键。大多数表都有一个包含多个列的唯一索引 现在我们想要使用应用服务器(jboss)和ejb模型。所以我创建了一个这样的类: @Entity @Table (name = "eakopf_t") public class Eakopf implements
@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创建的每个接口都可以决定使用哪个版本的表
这是扩展表类
@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)
有人有主意吗
许多问候,
Hauke这样做意味着休眠,即在一个表中存储两种不同类型的实体。如果使用鉴别器列,这是可能的。但如果我理解正确,您只需要表中的一种实体:Eakopf6001。在这种情况下,它的基类应该用
@MappedSuperClass
注释,而不是用@Entity
注释
我建议创建一个用@mappedenty
注释的类(我们称之为BaseEakopf)和两个实体:EaKopf和EaKopf6001,每个实体都有一组附加字段。根据要使用的实体,在映射类列表中包含另一个实体
我个人的观点是,如果你有多个版本的应用程序,它们应该使用相同的实体,但字段不同。您的版本控制系统将负责这些多个版本,而不是您的源代码(即,每个版本的应用程序都有一组源文件,而不是所有可能的版本都有一组源文件)。我们有一个包含三个部分的eakopf\t表。现在我为客户开发了一个接口,我知道只需要这三个字段,所以我可以使用Eakopf.java。几周后,我们向表中添加了一个新字段,我为不同的客户创建了另一个接口,对于该接口,我需要所有四个字段。我的想法是扩展eakopf.java类,并将新字段放在扩展类(eakopf6001.java)上。一个是第二个接口(对于具有此附加字段的客户),我使用eakopf6001.java。最好的方法是将这个新字段添加到eakopf.java中。但是如果我为数据库模式没有第四个字段的“第一个”客户进行更新,我会遇到麻烦,因为hibernate找不到该字段。这是一个好的做法吗?是否适合声明所有基本实体并创建扩展这些实体的模型?