My project is a WAR project generated with seam-gen. It contains a RESTEasy web service class like this (simplified, only the relevant parts):
@Scope(ScopeType.APPLICATION)
public abstract class RestService {
@In
protected EntityManager entityManager;
@GET
@POST
@Produces("application/json")
public Object proxy() {
// invokes various subclass methods
// based on request parameters
// and returns the result
}
// further method and logic
}
And:
@Path("/my")
@Name("myRestService")
public class MyRestService extends RestService {
public Object login(/*...*/) {
User user = getUser(email);
// ...
Token token = user.getToken();
if (token != null) {
entityManager.remove(token);
}
token = new Token();
entityManager.persist(token);
user.setToken(token);
user.setLastlogin(new Date());
entityManager.persist(user);
// ...
}
private User getUser(String email) {
try {
return (User) entityManager
.createQuery("FROM User WHERE UPPER(email) = UPPER(:email)")
.setParameter("email", email)
.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
}
If i invoke the login method through a web browser, it finds the correct user (based on the get params), instantiates a Token for it (i can see at the STDOUT of Hibernate asking the databse for the next sequence), but the persist() method does not save the Token to the database, neither the modifications of the User object (token id, last login date).
I have googled this for two days now, here's what i could figure out:
my project uses SEAM managed transactions (components.xml):
<persistence:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/MyEntityManagerFactory"/>
my project uses JTA for transaction handling (persistence.xml):
<persistence-unit name="MyProject" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> ...
the EntityManager.persist() does NOT commit changes to the database, just queues changes to the current transaction (?)
the SEAM managed Transactions are tied to conversations by default
I tried to use .flush(), an exception was thrown saying that there is no transaction in progress.
I tried to use .joinTransaction() and .getTransaction().begin(), another exception was thrown saying that a JTA EntityManager can not access transactions.
Also tried to use different scope types on the class, or use the @Transactional annotation on my login() method, no luck.
Also tried to inject the EntityManager with the @PersistenceContext annotation, this resulted in an exception saying @PersistenceContext can only be used with session beans.
Also tried to mark my class as @Stateless, this resulted that i could not reach my service (404).
How should i persist my Entities within a RESTEasy service with EntityManager?
System specs:
- JBoss 5.1.0 GA
- SEAM 2.2.1 Final
- Postgres 8.3
Please note that i'm totally new and inexperienced with JavaEE/JBoss/SEAM.
Any comment would be useful! Thanks.