0

I needed a RoleMappingService class(which is annotated by @Service) object into a Employee class (which is annotated by @Entity)

below are my classes

********************* RoleMappingsService class **********************

@Service
public class RoleMappingsService {
    @Autowired
    RolesMappingDao rolesMappingDao;


    public List<RolesMappings> getRolesMappingByauthSystemRole(String authSystemRole) {
        return rolesMappingDao.getRolesMappingByauthSystemRole(authSystemRole);
    }

}
############### Employee class
@Configurable
@Component
@Entity
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
public class Employee implements Serializable, UserDetails {

    @Autowired
    @Transient
    RoleMappingsService roleMappingsService;

    public static final String STATUS_ACTIVE = "ACTIVE";
    public static final String STATUS_INACTIVE = "INACTIVE";
    public static final String STATUS_LOCKED = "LOCKED";
    public static final String STATUS_ONLEAVE = "ONLEAVE";
    public static final String STATUS_EXPIRED = "EXPIRED";

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "emp_id")
    private String empId;

    @Column(name = "emp_password")
    private String empPassword;

    @Column(name = "emp_email")
    private String empEmail;

    @Column(name = "emp_address")
    private String empAddress;

    @Column(name = "emp_age")
    private int empAge;

    @Column(name = "emp_firstname")
    private String empFirstname;
}

Here Autowire is not working for roleMappingsService and the object is always found null. However I tried to autowire same object in some other service and there Autowire is perfectly working.

( I know Entity class is only used for representing database table but in my case I need to set some field values which depend on another table so need to fetch data using service)

Prasad Parab
  • 437
  • 1
  • 7
  • 26
  • 1
    You need to change your architecture. Entities shouldn't depend on the service layer. And Entities are not Spring beans, so you can't autowire any Spring bean into an entity. Anntating an entity with Component makes no sense. – JB Nizet Jul 22 '18 at 18:58
  • I have tried to get that roleMappingsService with use of helper class, in which I write one static helper class and trough that class tried to get roleMappingsService object but still no luck. – Prasad Parab Jul 22 '18 at 19:17
  • Again, you shouldn't do that. Forget about this idea. Use entities from services, not vice-versa. – JB Nizet Jul 22 '18 at 19:20

1 Answers1

3

JB Nizet is totally right

I'll try to provide more explanations here.

Spring can Autowire only beans, objects that it manages, and not arbitrary objects.

Entities are usually created from within a JPA (Hibernate) and are not something that you want to manage by Spring.

There is a related discussion available here but bottom line you should never do something like this.

Why not? Here are a couple of questions/reasons:

  • Maybe these entities will go outside spring context at all (serialization), what should that reference contain? Should we also serialize the service? How?

  • What will happen if the method that turns to the service will be called "outside" the spring driven application (maybe even in different JVM)?

  • If there are, say 1000 objects returned by that query, do you really want all of them to reside in application context? Or maybe should they be of "prototype" scope?

As you see, it doesn't play nice with spring concepts. I think the reason for it is that Hibernate and JPA do not "support" an idea of methods inside entities, it's just a different framework. I know there are other frameworks that do allow such a concept, but Hibernate/JPA just doesn't, period

So instead of trying to inject the service into the entity bean, probably you should redesign the application so that the service method will be called from outside, maybe via some facade, and entities will be just populated by query, and then "enriched" with additional information if we're talking about SELECT queries, or, alternatively, some information should be pre-set on entity objects, generated by the Business Logic Layer and only then the entity object should be stored in DB

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97