Query regarding EJBLocalObject remove() working for JBoss AS - jboss5.x

I am currently using JBoss 5.1.0 GA build for deploying my enterprise application. Am facing a strange issue w.r.t the working of EJBLocalHome remove() API. I have an Entity Bean say"Emp". I needs to delete an entity bean say 'emp1'. Hence i will call the EJBLocalObject remove() which will call the "Emp" EntityBean#ejbRemove() API to remove the bean from my database.
remove() -> ejbRemove()
In case of Jboss AS, i observerd that when i call the remove() API, the ejbStore() API is being called first and then ejbRemove() API in the same transaction. During remove() API the Entity Bean is not being modified. Hence ejbStore() should not be called. But it does. Hence the sequence is:-
remove() -> ejbStore() -> ejbRemove()
I deplyed my application on Websphere AS, and when i called the remove() the call sequence was:-
remove() -> ejbRemove() . ejbStore() was not being called in this case.
Can anybody tell why such beahviour occurs in case of JBoss AS ? I feel ejbStore() should not be called as nothing has been updated and working should be similar to Webspehere.
-Ajit

It seems like JBoss specific issue. Saw the internal implementation of JBoss and found that it calls ejbStore when the the configuartion element 'sync-on-commit-only' is set to false. This property is present in the standardjboss.xml file and the default value is false. This is what the Jboss specification says for this element:-
"This configures a performance optimization that will cause entity bean state to be synchronized with the database only at commit time. Normally the state of all the beans in a transaction would need to be synchronized when an finder method is called or when an remove method is called, for example."
Hence if 'sync-on-commit-only' is set to false then ejbStore() is called so that the entities are in sync with the datastore before the bean is removed.
The only thing i noticed that irrespective of whether this property is set to true/false the entity bean will be removed from the datasource. hence it still leaves me wondering why an ejbStore() call is required during remove() as eventually the bean will be removed from the datasource and put back to the instance pool.
-Ajit

Related

#EnableJpaRepositories.enableDefaultTransactions = false not working

The JavaDoc reads
Configures whether to enable default transactions for Spring Data JPA repositories. Defaults to true. If disabled, repositories must be used behind a facade that's configuring transactions (e.g. using Spring's annotation driven transaction facilities) or repository methods have to be used to demarcate transactions.
I debugged into the framework, and there it just creates a transaction if none exists, even with enableDefaultTransactions = false.
As far as I can see, Spring Data JPA Repositories are pre-configured with #Transactional(readOnly=true) (see SimpleJpaRepository), which leads to nobody noticing when a programmer forgot to properly annotate his service or job with the proper #Transactional because Spring Data JPA creates a transaction for every repository method that's called.
I wanted to disable it. First try was putting a #Transactional(MANDATORY) on my repository super interface. That wasn't working.
Then I noticed "enableDefaultTransactions" in the #EnableJpaRepositories annotation. I set it to false, but nothing changed. The JavaDoc lead me to believe that it would do exactly what I wanted: to remove the default transaction support and throw an exception when using a repository without already being in a transaction context.
Am I wrong? Is this a bug? Is enableDefaultTransactions intended any other way?
Using spring data jpa 1.9.0.RELEASE.
The intention of enableDataTransactions=false is to remove the default transaction management from the implementation (I guess from SimpleJpaRepository). It will behave as if no #Transactional was specified. Then you can control transactions in the service layer.
https://jira.spring.io/browse/DATAJPA-685
However, regardless of the enableDataTransactions parameter, if you add your own #Transactional annotation in your repository interfaces, it will be correctly applied.
However, however! If you specify #Transactional on the type level, the Spring framework itself (unrelated to data and JPA projects) will apply it only to methods declared in that type, not to the inherited methods. I find this behavior to be correct! Only by overriding the method, you can change its specification and implementation.
#Transactional(propagation=Propagation.MANDATORY)
public interface MyRepository extends CrudRepository<Something, Long> {
#Override
public Something findOne(Long id);
}
In this sample, MANDATORY propagation will apply to findOne, but it won't to findAll.
Note: Even though I find this behavior correct, I still don't like that there is no standard way to configure the MANDATORY propagation globally. In my opinion, it should even be default.
There were bugs with this in previous releases. I used Spring 4.2.2 and Sprint Data 1.11.0 to test it.
Bug reports:
https://jira.spring.io/browse/DATACMNS-715

Should a GWT RequestFactory Locator method expect a passed-in JPA entity to be attached or detached?

Right now I have to call JPA merge() at the end of my service method to persist changes. I'm doing this because our servlets do not start a transaction before the Locator.find() runs. They start them later in the service method.
I know that RequestFactory uses my Locator find() and updates the object based on what the client sent to the server, so I was just wondering if maybe that object should be an attached object and therefore allow JPA to handle the changes "naturally" rather than explicitly call merge().
Or perhaps this just depends on the situation?
I don't know JPA much, but I confirm that you SHOULD scope your transactions to your service methods: a RequestContext is a batch of requests that can each succeed or fail independently, putting them all in a single transactions would violates that principle. There are also cases where your Localor#find can be called, changes applied to the entity, but then the entity is never passed to any service method: you wouldn't want the changes to be persisted in this case.

What kind of transaction context does an injected EntityManager have in an EJB whose transaction context is TransactionAttributeType.NOT_SUPPORTED?

Suppose I have an EJB that is annotated with:
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
Suppose further that it has an EntityManager injected into it:
#PersistenceContext
private EntityManager em;
If I perform various operations on the EntityManager, will a resource-local transaction be started and committed for each such operation? Or will there be one for all of them? Or is this behavior undefined by the JPA specification? I could not find a suitable paragraph either way in either the JPA 2.0 specification or the EJB 3.1 specification.
I understand that there will not be a JTA transaction started for the EJB method, but I am not clear on what kinds of transactions will be in effect for the underlying EntityManager. I am presuming that the behavior is undefined but I'm hoping that someone from the larger StackOverflow community knows better, or has insight into this area of the specification, or into the discussions that dealt with this area.
Below are the few excerpts from JSR 318 & section 13.6.5 might clear most of the questions.
13.6.2.1 NOT_SUPPORTED
The container invokes an enterprise bean method whose transaction
attribute is set to the NOT_SUPPORTED value with an unspecified
transaction context.
If a client calls with a transaction context, the container suspends
the association of the transaction context with the current thread
before invoking the enterprise bean’s business method. The container
resumes the suspended association when the business method has
completed. The suspended transaction context of the client is not
passed to the resource managers or other enterprise bean objects that
are invoked from the business method.
If the business method invokes other enterprise beans, the container
passes no transaction context with the invocation.
13.6.5 Handling of Methods that Run with “an unspecified transaction context”
The EJB specification does not prescribe how the container should
manage the execution of a method with an unspecified transaction
context—the transaction semantics are left to the container
implementation. Some techniques for how the container may choose to
implement the execution of a method with an unspecified transaction
context are as follows (the list is not inclusive of all possible
strategies):
The container may execute the method and access the underlying resource managers without a transaction context.
The container may treat each call of an instance to a resource manager as a single transaction (e.g. the container may set the
auto-commit option on a JDBC connection).
The container may merge multiple calls of an instance to a resource manager into a single transaction.
The container may merge multiple calls of an instance to multiple resource managers into a single transaction.
If an instance invokes methods on other enterprise beans, and the invoked methods are also designated to run with an unspecified
transaction context, the container may merge the resource manager
calls from the multiple instances into a single transaction.
Any combination of the above.
As mentioned above in specification section 13.6.2.1, the context interaction between the client & container is being described.
In section 13.6.5, the underlying mechanism of container for handling such transaction is being described, but it depends on the implementation.
As pointed by Nayan Wadekar, the EntityManager will have no transaction associated.
In your example you specified a transaction-scoped EntityManager (default value if not specified otherwise). This implies that methods requiring an active transaction will throw a TransactionRequiredException, like persist:
[Throws] TransactionRequiredException - if invoked on a container-managed entity manager of type PersistenceContextType.TRANSACTION and there is no transaction

How to persist JPA entities even when EJB method throws an exception?

I have an EJB, whose method (among other things) persists JPA entity. If the method throws an error, the transaction is rolled back and the entity is not persisted.
However, I do want that entity to be persisted regardless of any exceptions, that might occur in the EJB method.
I'm using WebSphere 7.0, EJB3.0, JPA 1.0 (OpenJPA that is in WAS), DB2, if it matters.
I tried setting #TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) on top of EJB; with that, entity is not persisted even if there is no exception. I also tried commiting transaction myself (em.getTransaction().commit()), but getTransaction() throws exception (because transactions are managed by container).
Use bean-managed transactions.
#Stateless
#TransactionManagement(TransactionManagementType.BEAN)
public class MyEJB {
#PersistenceContext(unitName="...")
private EntityManager _em;
#Resource
private UserTransaction _utx;
public void myEJBMethod() {
_utx.begin();
// Use _em
_utx.commit();
// Do other work that might throw an exception.
}
}
Alternatively, use TransactionAttributeType.REQUIRES_NEW as suggested by edalorzo.
I am not an expert on EJBs, but I have been dealing with JPA and transactions for a few days now.
I recently answered another question about how entities resided in a context, and how this works in Java EE applications, the context is linked with your JTA transaction.
You can see details of this answer by clicking here. I think it is useful to understand how to context works in order to comprehend the nature of problems like the one you describe.
If you do not provide transaction support, then there is nothing to persist from the container standpoint, and therefore, your changes to the context are transient.
Also you have to consider that once an exception occurs, your context becomes invalid, and the entities in it get detached. (There are a few exceptions to this, like NoResultException).
Thus, from that point on, if you want to commit something, you need a new JTA transaction, with a new fresh JPA context in order to be able to commit changes to the database.
As I said, I am not an expert in EJBs, but if your method fails due to exceptions and you still would like to retry the transaction again by re-invoking the method, then you could force a new transaction to be created every time the method is invoked and by this, you would create a new fresh JPA context.
On the other hand, if you want your modifications to the entities to be persisted, regardless of exceptions in the method, then you might like to consider moving the code that is updating the entities to a new EJB method defined to start a new transaction (TransactionAttributeType.REQUIRES_NEW) every time you invoke it.
By the time this second inner method finishes, your work over the transactions will be automatically flushed to the database, regardless of the outer method of you EJB failing.
Basically, you would be providing a new context for your entities, and linking such context to a new transaction, scoped to commit when the inner method completes.
The natural behavior in EJB containers, as far as I understand, is that ever method joins the already existing transaction, and this is what you might like to prevent, from my point of view.
Another alternative: if you want to control your context using a different transaction support then you might like to consider providing a resource-local based persistence unit and you can manually instantiate your entity manager and control transaction scope as you wish. But honestly, this does not sound like a good idea to me, at least no in the context of the problem that you described.

jpa hibernate when is an object managed

I have a test case, where i get an object by id using the entitymanager.find method. then I try to check if the object is in managed state by using entityManager.contains(). but contains comes up false. So when is an object in the persistant state such that contains return true.
The find-method can be invoked without a transaction, however, in such case the resulting entity (if found) will be in detached state if using EntityManager with "transaction-scoped persistence context". If the EntityManager has "extended persistence context", the result will be in managed state. If the find-method is called within a transaction, the resulting entity will be managed in both cases.
For more information about "transaction-scoped" vs. "extended" -persistence contexts, see here.
If you call find by id in the entity manager, the object will be managed while still within the transaction. Otherwise it becomes detached and you have to call entityMangerInstance.merge() to make an object managed.