Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject a spring's service bean into a JPA Entity?

My problem is very similar to this one : Injecting fields via Spring into entities loaded by Hibernate

The difference is that , I am using JPA2 entities , not hibernate . While the underlayer is still hibernate (3.5.5).

My spring version is 3.0.4.

What's the corresponding eventListeners in JPA's world ?

Sample code from the original post :

class Student {
   int id; //loaded from DB
   String name; //loaded from DB
   int injectedProperty; //Inject via Spring
   transient Service serviceImpl; //Inject via Spring
}

I know there may be aspectJ's solutions , but I'd rather like a pure-java solution. Thanks.

like image 436
smallufo Avatar asked Sep 19 '10 20:09

smallufo


People also ask

How do you inject specific beans in a Spring boot?

In Spring Boot, we can use Spring Framework to define our beans and their dependency injection. The @ComponentScan annotation is used to find beans and the corresponding injected with @Autowired annotation. If you followed the Spring Boot typical layout, no need to specify any arguments for @ComponentScan annotation.

How do you inject beans?

To use the beans you create, you inject them into yet another bean that can then be used by an application, such as a JavaServer Faces application. For example, you might create a bean called Printer into which you would inject one of the Greeting beans: import javax. inject.

How do you inject beans from one bean to another?

For a class annotated with @Component , specifying them is required for the autowired constructor but in a @Bean declaration you don't need to provide a parameter to specify the MyObject dependency to use (while it will work) if that is accessible in the current class, which is your case.

What is the difference between @inject and @autowired?

@Inject and @Autowired both annotations are used for autowiring in your application. @Inject annotation is part of Java CDI which was introduced in Java 6, whereas @Autowire annotation is part of spring framework. Both annotations fulfill same purpose therefore, anything of these we can use in our application. Sr.


1 Answers

What's the corresponding eventListeners in JPA's world ?

JPA has Entity Listeners (and Callback Methods). From the JPA 2.0 specification:

3.5 Entity Listeners and Callback Methods

A method may be designated as a lifecycle callback method to receive notification of entity lifecycle events. A lifecycle callback method can be defined on an entity class, a mapped superclass, or an entity listener class associated with an entity or mapped superclass. An entity listener class is a class whose methods are invoked in response to lifecycle events on an entity. Any number of entity listener classes can be defined for an entity class or mapped superclass.

(...)

The entity listener class must have a public no-arg constructor.

Entity listeners are stateless. The lifecycle of an entity listener is unspecified.

The following rules apply to lifecycle callbacks:

  • Lifecycle callback methods may throw unchecked/runtime exceptions. A runtime exception thrown by a callback method that executes within a transaction causes that transaction to be marked for rollback.
  • Lifecycle callbacks can invoke JNDI, JDBC, JMS, and enterprise beans.
  • In general, the lifecycle method of a portable application should not invoke EntityMan- ager or Query operations, access other entity instances, or modify relationships within the same persistence context. A lifecycle callback method may modify the non-relationship state of the entity on which it is invoked.

(...)

3.5.1 Lifecycle Callback Methods

Entity lifecycle callback methods can be defined on an entity listener class and/or directly on an entity class or mapped superclass.

Lifecycle callback methods are annotated with annotations designating the callback events for which they are invoked or are mapped to the callback event using the XML descriptor.

The annotations used for callback methods on the entity class or mapped superclass and for callback methods on the entity listener class are the same. The signatures of individual methods, however, differ.

Callback methods defined on an entity class or mapped superclass have the following signature:

void <METHOD>()

Callback methods defined on an entity listener class have the following signature:

void <METHOD>(Object)

The Object argument is the entity instance for which the callback method is invoked. It may be declared as the actual entity type.

The callback methods can have public, private, protected, or package level access, but must not be static or final.

(...)

Here is an example (from the spec):

@Entity
@EntityListeners(com.acme.AlertMonitor.class)
    public class Account {
    Long accountId;
    Integer balance;
    boolean preferred;
    @Id
    public Long getAccountId() { ... }
    ...
    public Integer getBalance() { ... }
    ...
    @Transient // because status depends upon non-persistent context
    public boolean isPreferred() { ... }
    ...
    public void deposit(Integer amount) { ... }
    public Integer withdraw(Integer amount) throws NSFException {... }

    @PrePersist
    protected void validateCreate() {
        if (getBalance() < MIN_REQUIRED_BALANCE)
            throw new AccountException("Insufficient balance to open an account");
    }

    @PostLoad
    protected void adjustPreferredStatus() {
        preferred = (getBalance() >= AccountManager.getPreferredStatusLevel());
    }
}

public class AlertMonitor {
    @PostPersist
    public void newAccountAlert(Account acct) {
        Alerts.sendMarketingInfo(acct.getAccountId(), acct.getBalance());
    }
}

In your case, you'll probably want PostLoad callback methods.

See also the Chapter 6. Entity listeners and Callback methods in the Hibernate Entity Manager documentation.

But to put it simply, what you want to do is not that simple with JPA and using AspectJ class weaving with the @Configurable annotation might be the best option.

References

  • JPA 2.0 Specification
    • Section 3.5 "Entity Listeners and Callback Methods"
like image 81
Pascal Thivent Avatar answered Sep 21 '22 06:09

Pascal Thivent