1

I have a method on a stateless session bean which creates a new instance of an entity and persists it. You might normally use new MyEntity() to create the object but I would like injection to populate some of the properties of the entity for me.

I got partial success using

@Inject 
@New 
private MyEntity myNewEntity; 

in the session bean and then using that instance in my method.

The problem I have now is that the second time the method is called, myNewEntity isn't a new object, its the same object as the one created the first time. As a result I'm getting

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '9' for key 'PRIMARY'

Or at least that's why I think I'm getting this exception. Certainly if I use new MyEntity() I don't get the exception but my injection doesn't happen.

Am I on the wrong track? How can I create a new local entity object while enabling injection?

Any help would be great!

Jonathan
  • 403
  • 3
  • 13
  • What is the primary key of the object and what is your injection framework defining as default values for those fields? – Edwin Dalorzo Jun 02 '11 at 00:00
  • 1
    My primary key is an auto generated id i.e. @Id @GeneratedValue(strategy = AUTO) private long id; I have a working solution now see below, not sure if this is 'right' – Jonathan Jun 07 '11 at 11:50

2 Answers2

2

First of all - I have serious doubts that it's a good idea to use CDI to control the lifecycle of a Entity. See this quote from the documentation (here):

According to this definition, JPA entities are technically managed beans. However, entities have their own special lifecycle, state and identity model and are usually instantiated by JPA or using new. Therefore we don't recommend directly injecting an entity class. We especially recommend against assigning a scope other than @Dependent to an entity class, since JPA is not able to persist injected CDI proxies.

What you should do to create new instances of entities is adding a layer of indirection, either with @Produces or @Unwraps (Seam Solder, if you need it to be truly stateless), and thereby making sure that you code explicitly calls new.

Jan Groth
  • 14,039
  • 5
  • 40
  • 55
  • Is a @Produces method that calls new with the default constructor different from the default behaviour without an @Produces method? – Jonathan Jun 07 '11 at 11:48
  • Caution: The quotation above is not from the official EE specs but from the JBoss Weld docs, there might be difference in other implementations. – jabal Oct 10 '12 at 12:47
  • 1
    To come back on this I found Jan's advise to be right. I used a different approach http://stackoverflow.com/questions/7830347/transparently-recording-the-last-modified-user-on-jpa-entity – Jonathan Nov 02 '13 at 08:01
0

I think I have a working solution now which seems okay, though I'm not quite sure why it works so I welcome your feedback on a better solution. I am now injecting a DAO-style bean into my stateless session bean:

@Stateless
public class PhoneService {

    @Inject
    protected ProblemReports problemReports;

An injecting my entity into the ProblemReports bean:

public class ProblemReports {

    @Inject
    @New
    private ProblemReport newProblemReport;

I assume that ProblemReports defaults to @Dependant scope which as I understand it should be the same as the stateless session bean which containts it. I could understand this if the scope of ProblemReports was shorter, causing a new instance of ProblemReport to be created when the new ProblemReports is created; but it isn't.

Is this just an example of EJB and CDI not playing well together?

Jonathan
  • 403
  • 3
  • 13
  • If ProblemReport is an entity, then this solution is a problem itself ;-). You definitely do not want any entities to be created as managed beans. See my answer below. – Jan Groth Jun 07 '11 at 13:22