2014-01-25 51 views
0

我正在尝试为以下情况找到最佳解决方案:我有一个必须进行代理的实体A.问题是,当我简单地通过扩展类A来创建抽象代理将其所有行为委托给包装的实体时,我最终会从该实体继承大量未使用的字段。但至少它不会改变持久性的工作方式。实体代理时的代理模式?

为了不这样做,我创建了一个抽象超类,它只包含抽象方法(public和protected,这就是为什么我没有使用接口)并且使它成为Entity和所有代理。这个解决方案似乎是最好的,但是它在持久性方面遇到了很多麻烦......

我想依赖我的应用程序层中的抽象超类(因为它不区分代理A和非-proxied -A),但是然后Hibernate不会让我 - 实体实例不能与抽象类有关系,因为它不被持久化上下文知道。当然,我可以贬低实体类,但它击败了目的......

有没有办法让Hibernate降低实体本身的实体?我的意思是,我可以在任何地方使用抽象类,但休眠会知道它的真正的实体类...

public abstract class AbstractA { 

    public abstract void doSomethingOnA(); 

} 


@Entity 
public class EntityA extends AbstractA { 

    @Id 
    private Long id; 

    @Column(name="column_in_a") 
    private SomethingA somethingA; 

    @Override 
    public void doSomethingOnA() { 
     somethingA.doSomething(); 
    } 

} 

public class ProxiedA extends AbstractA { 

    private AbstractA wrappee; 

    @Override 
    public void doSomethingOnA() { 
     doSomethingFirst(); 
     wrappee.doSomethingOnA(); 
    } 

} 

问题是,我想使用AbstractA代替EntityA也当涉及到持久性。问题是当另一个实体声明一个AbstractA类型的字段时,Hibernate将会失败。我知道为什么,问题是如何处理它?

谢谢!

回答

1

我倾向于做的是创建一个接口,例如用户。然后我将有一个POJO调用UserBean和一个实体调用UserEntity,它们都实现了该接口。然后,您可以执行以下两项操作之一:在实体中拥有一个构造函数,并使用该bean和createBean方法从实体创建bean。我没有在bean类中为实体构造一个构造函数,因为在我的场景中,我有一个没有JPA访问权的图层,所以这些bean不能具有实体的任何知识。

Hibernate或任何JPA提供程序会知道它何时会得到一个真正的UserEntity,并且如果您不小心将其发送给UserBean,它将会正确地投诉。很多时候我甚至没有实现相同的接口。这样我就可以强制执行,我不会在持久性边界上意外发送UserEntity而不是UserBean。

再次,我可能会误解你的问题,因为代名词有很多含义。例如,您可能正在谈论延迟加载代理作为实体的属性。或者你可能正在谈论一个远程代理。

1

没有看到代码,理解你所描述的内容是一个挑战。但通过你的描述看完之后,这里有一些想法:

  • 从面向对象的角度来看,如果延长EntityA导致许多不必要的成员,你的子类不觉得这是一个真正的子类。子类的一个实例实际上应该是EntityA的一个实例,它实际上只专注于行为并可能扩展父类的成员变量。
  • 从持久性的角度来看,如果你的子类不会使用许多组成EntityA的字段,那么你面临的问题是“不需要”的关系属性可能需要特殊处理或某种解决方法编码你的子类对象。

再次,这是很难做到无代码审查具体,但它听起来像是你可能要由成员变量和操作,这是共同的EntityA和你的抽象类重构到一个共同的开始父类。然后可以对父类进行注释以包含映射到列的真实体属性。从那里,你可以使用简单的Java继承和Hibernate的继承模式之一来完成您的实现:

  • Table per concrete subclass,这可能在Hibernate中使用XML映射一个<class>标签来定义,不需要额外的处理处理多态,因为Hibernate将扫描持久化类并了解超类或接口。
  • Table per concrete subclass with unions,这可能在Hibernate中使用XML映射一个<union-subclass>标签来定义,效果最好的时候,你不需要多态查询和使用,可能会涉及非持久性接口(UNION基)查询(这听起来像它可能是你的情况)。
  • Table per concrete subclass with joins,这可能在Hibernate中使用XML映射一个<joined-subclass>标签来定义,是最好的,如果你想(或必须使用)一个完全规范化的数据库架构。
  • Table per class hierarchy,这可能在Hibernate中使用XML映射一个<subclass>标签来定义的,是最简单,因为所有的子类映射到一个表,表现最好,但如果唯一列的定义才起作用子类可能是NULL
+0

事情是我提到的那些代理不会被持久化。它们缠绕在没有任何兄弟实体的单个实体中。请看我更新的问题。 – kboom