persistence icon indicating copy to clipboard operation
persistence copied to clipboard

Allow components other than stateful sessions beans to initiate container-managed extended persistence contexts

Open lukasj opened this issue 14 years ago • 9 comments

It might be useful to support the use of container-managed extended persistence contexts in singleton session beans and/or application-scoped or conversation-scoped CDI components.

lukasj avatar Dec 05 '11 21:12 lukasj

  • Issue Imported From: https://github.com/javaee/jpa-spec/issues/3
  • Original Issue Raised By:@glassfishrobot
  • Original Issue Assigned To: @ldemichiel

lukasj avatar Aug 31 '18 16:08 lukasj

@glassfishrobot Commented Reported by @ldemichiel

lukasj avatar Dec 05 '11 21:12 lukasj

@glassfishrobot Commented donatasc said: +100

IMHO this was a huge miss in Java EE 6. Even though CDI introduced conversation scope, injection/creation of extended persistence context EM was not mentioned at all. EJB spec is also silent about extended PC, what caused me to post message like this to JPA mailing list: http://java.net/projects/jpa-spec/lists/users/archive/2013-01/message/51

In general, extended persistence context is largely under-specified in regards to integration between CDI/EJB/JPA.

lukasj avatar Feb 05 '13 06:02 lukasj

@glassfishrobot Commented kostd said: In fact it is working now. I think before (on java 6) its already worked, but not sure.

Checked in environments:

Environment1: java7u80, wildfly 8.2.0.Final, wildfly-jpa-8.2.0.Final, hibernate 4.3.7.Final, weld 2.2.6.Final, wildfly-ejb3 8.2.0.Final, extended-persistence inheritance = DEEP(default) Environment2: java8u77, wildfly 10.0.0.Final, wildfly-jpa-10.0.0.Final, hibernate 5.0.7.Final, weld 2.3.2.Final, wildfly-ejb3 10.0.0.Final, extended-persistence inheritance = DEEP(default)

have:

@ConversationScoped
public class CDIBean1 implements Serializable{

	private static final long serialVersionUID = 1L;

	@Inject
	CDIBean2 cdibean2;

	@Inject
	StatelessBean statelessBean;

	public void doSomthing(){

		cdibean2.doSomthing();
		statelessBean.doSomthing();

	}
}
...

@ConversationScoped
public class CDIBean2  implements Serializable{

	private static final long serialVersionUID = 1L;

	@PersistenceContext(type=PersistenceContextType.EXTENDED, synchronization=SynchronizationType.UNSYNCHRONIZED)
	EntityManager em;

	public void doSomthing(){

		List<StreetType> streets  = em.createQuery(" from StreetType").getResultList();

		SessionImpl session = (SessionImpl) em.unwrap(SessionImpl.class);
		System.out.println("there are " + session.getPersistenceContext().getNumberOfManagedEntities() + " entities in XPC after initiation");
	}
}
...

@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class StatelessBean {

	@PersistenceContext
	EntityManager em;

	public void doSomthing(){

		SessionImpl session = (SessionImpl) em.unwrap(SessionImpl.class);

		System.out.println("there are " + session.getPersistenceContext().getNumberOfManagedEntities() + " entities in transaction-scoped persistence context");

	}

}

after call CDIBean1#doSomething() can see that XPC was initiated in CDIBean2#doSomething() and propogated as TxPC in stateless EJB. Both output strings show same managed object count in persistence context.

I vote to reviewing of "7.6.3 Container-managed Extended Persistence Context" in JPA-SPEC 2.1:

A container-managed extended persistence context can only be initiated within the scope of a stateful session bean. It exists from the point at which the stateful session bean that declares a dependency on an entity manager of type PersistenceContextType.EXTENDEDis created, and is said to be bound to the stateful session bean.

this is not truth truth is:

A container-managed extended persistence context can only be initiated within the scope of a stateful session bean or CDI bean. It exists from the point at which the bean that declares a dependency on an entity manager of type PersistenceContextType.EXTENDED is created, and is said to be bound to that (stateful or CDI) bean.

lukasj avatar Jul 04 '16 17:07 lukasj

@glassfishrobot Commented This issue was imported from java.net JIRA JPA_SPEC-3

lukasj avatar May 05 '17 06:05 lukasj

Is this working in a CDI/Servlet container?

hantsy avatar Apr 12 '21 12:04 hantsy

There are some existing work in Apache DeltaSpike, https://deltaspike.apache.org/documentation/jpa.html#ExtendedPersistenceContexts

hantsy avatar Apr 17 '21 04:04 hantsy

Extended persistence contexts really never took off and are now quite old fashioned. I suggest just closing this to reduce clutter.

Reza Rahman Jakarta EE Ambassador, Author, Blogger, Speaker

Please note views expressed here are my own as an individual community member and do not reflect the views of my employer.

m-reza-rahman avatar Apr 27 '21 03:04 m-reza-rahman

I don't quite understand what is being requested by this issue: naïvely it seems to me that this is a concern of the CDI spec, and is indeed already required.

However, you would be expected to use @Inject to obtain the persistence context, not @PersistenceContext.

gavinking avatar Apr 28 '21 11:04 gavinking

I believe that, even if this wasn't covered before, it's now covered by #460, which lets you specify a CDI scope for an injectable EntityManager (so you could use @ConversationScoped if you like).

gavinking avatar Aug 12 '23 22:08 gavinking

I'm going to comment on #460 after catching up on the contained thread. I'm commenting here with some reference info that is mostly just a links into the Spec and some notes:

Persistence container implementations are handling the container-responsibilities (7.9.1 container-responsibilities that describe what applications can expect with stateful session beans with extended persistence contexts.

With application-managed persistence contexts (e.g. EntityManagerFactory instance is made available to application code), Jakarta EE Applications already have the ability to manage their own equivalent of a container-managed extended persistence context except the application is in charge of carefully managing access to each subsequently obtained persistence context (applications carefully avoid accessing the same persistence context from multiple concurrent threads at the same time and are respectful of managing JTA transactions as well for each persistence context).

To me, this issue is about allowing Jakarta EE Persistence/JPA containers (or Persistence Providers) to provide the equivalent management of extended persistence contexts as described in the Specification, such that the application doesn't have manage their multiple threaded use of a persistence unit/context, instead applications just use the equivalent of an extended persistence context as previously managed by a Jakarta EE implementation, with the last request that uses each extended persistence context closing the extended persistence context.

I will read #460 soon and comment there.

scottmarlow avatar Aug 22 '23 14:08 scottmarlow

@scottmarlow Right, I understand that. But if you can define a CDI bean of type EntityManager with scope @Dependent, then that's already an "extended persistence context" with the same semantics as a container-managed extended persistence context in JPA.

Or, if you have a well-defined conversation scope, you can define the EntityManager as @ConversationScoped, and that's an even better sort of "extended persistence context"

gavinking avatar Aug 22 '23 14:08 gavinking

@scottmarlow Right, I understand that. But if you can define a CDI bean of type EntityManager with scope @Dependent, then that's already an "extended persistence context" with the same semantics as a container-managed extended persistence context in JPA.

Does that include the extended persistence context inheritance capabilities as mentioned in Persistence spec section 7.6.3.1?

I recall that as described by section 7.6.3.1, the expected Jakarta EE implementation is for shallow inheritance between direct stateful EJB beans calls although WildFly/Hibernate has always supported deep inheritance between any stateful EJB beans on the call stack (since JBoss AS 5+).

Also section 7.6.3.1 mentions that the extended persistence inheritance will occur for stateful session bean call stacks that use transactions or don't use transactions which implies that as each EJB stateful bean invokes another bean that something is tracking which extended persistence contexts are used by the calling bean and the called bean with some type of reference counting to know when we transition to zero beans using a extended persistence context (or let the garbage collector clean it up but I think that is problematic, at least it was when I tried it).

Some code links that deal with EJB stateful bean tracking to know when to close the extended persistence context are https://github.com/wildfly/wildfly/blob/main/jpa/subsystem/src/main/java/org/jboss/as/jpa/interceptor/SFSBDestroyInterceptor.java + https://github.com/wildfly/wildfly/blob/main/jpa/subsystem/src/main/java/org/jboss/as/jpa/interceptor/SFSBCreateInterceptor.java

The advantage of wiring all of the ^ tracking into the application server is that it makes it easier for applications to share a persistence context between multiple beans without the application being concerned about knowing when to close the extended persistence context.

Or, if you have a well-defined conversation scope, you can define the EntityManager as @ConversationScoped, and that's an even better sort of "extended persistence context"

I'm not sure that we would get the same inheritance capabilities as described in section 7.6.3.1 with conversation scope but yes, having the well-defined conversation scope EntityManager would be cleaner than having several stateful EJB beans each touching managed entities in the shared persistence context. However, I think the spirit of this issue was more for someone migrating a large application that depends on extended persistence context inheritance as described in section 7.6.3.1.

So if I am correct in my above statements, we might want to consider the bigger picture of how we want to help such users to migrate to use conversation scope persistence contexts. What I mean is that perhaps the extended persistence context inheritance should be eliminated for these users in that they would kind of squash (in the git sense) all of their stateful session beans that depend on extended persistence context inheritance.

scottmarlow avatar Aug 22 '23 16:08 scottmarlow

Good point. @Dependent would not give you inheritance, but @ConversationScoped would give you something a bit better.

gavinking avatar Aug 22 '23 18:08 gavinking

So I wondered whether it's possible to define some sort of pseudo-scope which implements the semantics of PC inheritance in CDI, but I don't believe it is. With SFSB, you have a way for one to explicitly instantiate another, and that instantiation operation is what causes the PC to be propagated/inherited. In CDI there's nothing really equivalent to that instantiation operation, so I don't really see how it could be defined.

gavinking avatar Aug 22 '23 19:08 gavinking