是否有一种方法可以覆盖由EntityManager提供的EclipseLink?我想重写EclipseLink's EntityManager.remove()方法--我不希望物理删除(只是逻辑的)。扩展适当的EntityManager很容易
public class MyEntityManager extends org.eclipse.persistence.internal.jpa.EntityManagerImpl {
public MyEntityManager(String sessionName) {
super(sessionName);
}
public void remove(Object entity) {
AbstractEntity en = (AbstractEntity)entity;
en.setAuditRD(33333);
this.merge(en);
}
}但是如何将其传递到EclipseLink的工厂来创建MyEntityManager而不是org.eclipse.persistence.internal.jpa.EntityManagerImpl呢?也许有任何参数,我可以在persistence.xml文件中传递吗?
发布于 2014-04-16 13:29:49
在persistence.xml类中,有一个provider元素,它决定了这一点。只需将提供程序的实现(而不是EntityManager)放在那里即可。摘录自JPA规范:
8.2.1.4提供者 provider元素指定持久性提供程序的javax.persistence.spi.PersistenceProvider类的名称。provider元素是可选的,但如果应用程序依赖于正在使用的特定持久性提供程序,则应指定该元素。
文件示例:
<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="myapp">
<provider>org.mydomain.ejb.MyPersistenceProvider</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
</persistence-unit>
</persistence> 发布于 2014-04-14 09:06:21
我认为重写实体管理器的默认行为是不适当的。如果你真的需要删除一个实体,那就不可能了。
最好有一些帮助器包装类来封装这些方法,而不是直接访问实体管理器&然后根据需要委派请求。
下面是伪码。
/** Use this wrapper class instead of EntityManager*/
class DBManager {
/** Implementing required methods*/
remove(E e){
em.remove(e); //-- Removing entity from DB
}
/** Give any appropriate method name to use application wide
and implement custom logic, discarding entity logically */
markInActive(E e){
AbstractEntity en = (AbstractEntity)e;
en.setAuditRD(33333);
em.merge(en);
}
}发布于 2014-04-16 13:25:56
EcliseLink支持软deltes,而不需要覆盖EntityManager。详情请参见http://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete。这允许您更改EclipseLink使用的delete查询,这样它就可以更改字段值,而不是删除。您可以添加@AdditionalCriteria,以防止通过查询读取已删除的记录,从而使它们看起来也已删除。
否则,您就不能仅仅在EclipseLink EntityManagerImpl上重写remove方法,除非您确信您永远不会使用级联或私有。remove方法将工作委托给内部方法,对每个映射都有更多的了解,因此,如果使用任何级联选项,还需要覆盖或拦截内部调用。如果您不打算使用级联选项,我将创建您自己的一组持久性提供程序类和一个使用这些类的新持久性单元。然后,提供程序类将获得第一个持久性单元并将其委托给它--类似于大多数容器使用代理类注入工厂和EntityManagers的方式。
https://stackoverflow.com/questions/23047771
复制相似问题