Domanda

I would like to override the EntityManager.remove() method for certain entities so that I can set an active boolean attribute to false rather than remove the object from the database entirely. This can be seen as a soft delete.

The remove method in the Entity_Roo_Jpa_ActiveRecord.aj file for my class (called Entity, used as a superclass) looks like:

@Transactional
public void remove() {
    if (this.entityManager == null) this.entityManager = entityManager();
    if (this.entityManager.contains(this)) {
        this.entityManager.remove(this);
    } else {
        Entity attached = Entity.findEntity(this.id);
        this.entityManager.remove(attached);
    }
}

I've found the definition of which EntityManagerFactory to use in META-INF/spring/applicationContext.xml:

<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

Would it be possible to subclass LocalContainerEntityManagerFactoryBean and provide my own EntityManager for a certain class, or is there a better way?

I've also noticed the use of @PersistenceContext to declare an attribute for the EntityManager:

@PersistenceContext
transient EntityManager Entity.entityManager;

But I suspect this is merely to store the EntityManager object and not to specify which implementation class to use (since EntityManager is an interface).

EDIT: The answer may lie in this answer.

È stato utile?

Soluzione

There are a couple of ways you can do this.

1. Push-in refactor the remove() method

Instead of going all the way to change the entityManager, you can push-in refactor the remove() method to your entity class and set the active value to be false within the method and call merge().

Also note that you would need to modify the finders and most other methods to filter the entities which are set to be active=false.

2. Spring Roo Behaviors Add-on @RooSoftDelete annotation

You can also use the following Spring Roo addon which enables a soft delete.

https://redmine.finalconcept.com.au/projects/final-concept-spring-roo-behaviours/wiki/Soft-delete-annoation

It lets you add a new annotation named @RooSoftDelete which takes care of soft deletion.

Apart from the above, you can also write a custom entity manager factory that would take care of all as well.

Cheers.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top