2017-10-20 70 views
2

这个问题对我来说很难制定。随时询问是否需要澄清。嵌入式类和双向关系

情况:我有一个使用Hibernate的Spring应用程序在数据库中保存不同的实体类。为简化调用这些类E1, E2, .., E20。所有这些类都基于相同的摘要@MappedSuperclass,但没有真正的继承(在数据库方面)。

现在我想添加新的实体类(En1, En2, ...)并建立双向关系到一些现有的实体。假设En1E1,E2,E3一个维吾尔,我的代码看起来是这样的:

@Entity 
public class E1 extends SuperClass { 
    //other attributes 

    @OneToMany(mappedBy = "e1") 
    List<En1> newAttribut; 

    public En1 doMagic(En1 entity) { 
    //a long function which does somthing with the entity 
    } 

    //other attribute 
} 

//-----------------------------// 
// The same code for E2 and E3 // 
//-----------------------------// 

@Entity 
public class En1 { 
    //other attributes 

    @ManyToOne 
    E1 e1; 

    @ManyToOne 
    E2 e2; 

    @ManyToOne 
    E3 e3; 

    //other attributes 
} 

问题:该解决方案适用不舒服。我需要为每个关系在类En1中指定一个属性,并且必须在每个现有实体中复制doMagic()方法。此外,在实践中,实体En1将一次只与另一个实体有关系。因此三个属性中的两个将是null

试图解决方案:@Embeddable的使用解决了重新实现相同的代码的问题E1,..,E3

public class EmbeddedEn1 implements Serializable { 

    @OneToMany(mappedBy="parentEntity") 
    private List<En1> newAttribut; 

    public En1 doMagic(En1 entity) { 
    //a long function which does somthing with the new entity 
    } 
} 

但不能建立在"parentEntity"双diretion。

继承不工作:当然,我可以用一类像hasAttributEn1E1,E2,E3继承,但这并不与其他新实体 - 类扩展。假设下面的情况,其中新的实体En2,..,En4应该是相对于以下实体:

  • En2 <-> E1, E3
  • En3 <-> E2,E3
  • En4 <-> E1,E2

在这种情况下,就需要多继承。

任何建议如何解决这个问题,而无需重复的代码?

回答

0

您可能想要为E1,E2,...,E20定义泛型类型,这样您只需要使用E类型的单个集合定义En类。 E的每个实现可以是不同的,但是你不需要改变你的En类,因为它只是保存E类型的集合。

Here's a link to a guide that may help.

+0

我在我的项目中使用通用DAO。但是这个问题对应于模型结构,即实体的设计,而不是我可以访问它们的方式。 – Thanthla

1

我认为更好的解决您的模型,你可以使用hibernate inheritance

+所以对于实体En1的情况下,创建E1,E2,E3...一个父类:

@Entity 
// TABLE_PER_CLASS will create a table for each subclass with all attributes 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
//.... 
//Abstract entity, so you won't need to create a table for it 
public abstract class E extends SuperClass { 

    // shared attributes & methods 
    @OneToMany(mappedBy = "e") 
    private List<En> newAttribut; 

    public En doMagic(En entity) { 
     //a long function which does something with the new entity 
    } 
    //... 

}

  • 删除doMagic(En1)newAttributeE1,E2,E3,因为他们会从父继承他们E

更新

正如您在您的评论中提到(和你的问题为好),你需要E类与多个En类关联。 为简单起见,我将使用hibernate的继承En还有:

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public abstract class En{ 

    @ManyToOne 
    private E e; 

    // ... 

} 

所以每个En1, En2,..., Enx会从该类继承。

例如,如果你想节省En2 <-> E3 & En3 <->E3(这个例子是为了说明目的,并且不包括其他方面,例如交易):

En en2 = new En2();   
En en3 = new En3(); 
E e3 = new E3();  
en2.setE(e3); 
e3.getEn().add(en2); 

en3.setE(e3); 
e3.getEn().add(en3); 
session.save(e3) 
session.save(en2) 
session.save(en3) 

在您将满足您的约束结束:

复制方法的 doMagin()
  • 一,

  • 的子实体En(例如:En1)将一次仅与一个其他实体(例如:E1E3)关联。

+0

谢谢你的回答。但是,这正是解决方案,它不适用于多个'En *'。在我的问题**遗传不起作用**我试图解释为什么。我可以像你的示例代码中所示的那样创建抽象类,比如'class hasEn1',但是由于'En2'也应该与'E1'有关,所以我需要'E1'类的多重继承,例如'class E1 extends hasEn1 hasEn2 ',这在Java中是不允许的。 – Thanthla

+0

@Thanthla我已经更新了涵盖第二种情况的答案。 –