Eclipselink JPA, Oracle, Weblogic, Appelant Persistent à ne pas s'engager à la base de données
Je viens juste de commencer à prendre un coup d'oeil à la persistance java (pour le moment avec eclipse par défaut du fournisseur de eclipselink). Fondamentalement, il suffit de créer un objet et tente de persister à la base de données (Oracle). C'est ma compréhension que la valeur par défaut transactionality doit s'engager le nouvel objet à la base de données quand le retour de la méthode, mais rien ne semble se passer. Des idées?
@Stateless
public class RegisterUser implements RegisterUserLocal {
@PersistenceContext
private EntityManager entityManager;
public void registerNewUser(String username, String password){
User user = new User();
user.setPassword(password);
user.setUsername(username);
entityManager.persist(user);
entityManager.getTransaction().commit();
}
}
Persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="SCBCDEntities" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>examples.persistence.User</class>
<properties>
<property name="eclipselink.target-server" value="WebLogic_10"/>
<property name="eclipselink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:db4"/>
<property name="eclipselink.jdbc.user" value="SCBCD"/>
<property name="eclipselink.jdbc.password" value="123456"/>
<property name="eclipselink.logging.level" value="FINEST"/>
</properties>
</persistence-unit>
</persistence>
Classe D'Entité:
@Entity
@Table(name="USERS")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String username;
private String password;
public User() {
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
Aussi, pour répondre à des réponses à cette question, avec le code que j'ai listé les journaux d'une validation en cours d'exécution (détail supprimé par souci de concision)
[EL Finest]: 2010-01-05 22:58:07.468--UnitOfWork(25499586)--Thread(Thread[[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.
Default (self-tuning)',5,Pooled Threads])--PERSIST operation called on: examples.persistence.User@191ed96.
<Jan 5, 2010 10:58:07 PM EST> <Debug> <JTA2PC> <BEA-000000> <BEA1-001959ECF50B251A451D: [EJB examples.session.stateless.RegisterUs
er.registerNewUser(java.lang.String,java.lang.String)]: ServerTransactionImpl.commit()>
<Jan 5, 2010 10:58:07 PM EST> <Debug> <JTA2PC> <BEA-000000> <BEA1-001959ECF50B251A451D: [EJB examples.session.stateless.RegisterUs
er.registerNewUser(java.lang.String,java.lang.String)]: TX[BEA1-001959ECF50B251A451D] active-->pre_preparing
<Jan 5, 2010 10:58:07 PM EST> <Debug> <JTA2PC> <BEA-000000> <SC[mr_domain+AdminServer] active-->pre-preparing
er.registerNewUser(java.lang.String,java.lang.String)]: TX[BEA1-001959ECF50B251A451D] prepared-->committing
<Jan 5, 2010 10:58:07 PM EST> <Debug> <JTA2PC> <BEA-000000> <SC[mr_domain+AdminServer] pre-prepared-->committed
er.registerNewUser(java.lang.String,java.lang.String)]: TX[BEA1-001959ECF50B251A451D] committing-->committed
...
...
mais si j'ajoute 'flush' après l'persistent, j'ai obtenu un notransaction'...
[EL Finest]: 2010-01-05 22:44:55.218--UnitOfWork(113017)--Thread(Thread[[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.De
fault (self-tuning)',5,Pooled Threads])--PERSIST operation called on: examples.persistence.User@1717dea.
<Jan 5, 2010 10:44:55 PM EST> <Info> <EJB> <BEA-010227> <EJB Exception occurred during invocation from home or business: weblogic.
ejb.container.internal.StatelessEJBLocalHomeImpl@1509b8 threw exception: javax.persistence.TransactionRequiredException:
Exception Description: No transaction is currently active>
<Jan 5, 2010 10:44:55 PM EST> <Debug> <JTA2PC> <BEA-000000> <BEA1-001859ECF50B251A451D: [EJB examples.session.stateless.RegisterUs
er.registerNewUser(java.lang.String,java.lang.String)]: TX[BEA1-001859ECF50B251A451D] active-->rolling back
...
...
OriginalL'auteur MJ. | 2010-01-05
Vous devez vous connecter pour publier un commentaire.
Après beaucoup de recherches, y compris en essayant à la fois gérée par le conteneur d'utilisateur et géré les opérations, il semble que le problème est que la transaction-type est spécifié comme RESOURCE_LOCAL. Dans ce cas, les règles suivantes s'appliquent:
Dans mon cas, j'avais besoin d'utiliser le manager de l'usine pour accéder à l'entitymanager, et l'utilisation d'un persistenceUnit au lieu d'un persistenceContext. Le code suivant fonctionne très bien:
Des informations supplémentaires sur la configuration des transactions et les paramètres de la persistence.xml peut être trouvé ici: http://openejb.apache.org/3.0/jpa-concepts.html
OriginalL'auteur MJ.
Vous ne pouvez pas utiliser le EntityTransaction (em.getTransaction()) parce que vous êtes à l'aide d'une Gérée par le Conteneur Gestionnaire d'entités (injectée), de sorte que vous devez compter sur le conteneur pour les transactions. Avez-vous établi des transactionnel paramètres pour la Stateless Session bean dans le fichier XML? Si vous n'avez pas, alors il devrait fonctionner comme la valeur par défaut doit être "Nécessaire". Vous pouvez essayer de l'annotation 'registerNewUser" avec @TransactionAttribute(TransactionAttributeType.NÉCESSAIRE)
Vous pouvez également créer une transaction de l'utilisateur avant d'accéder à l'EM, mais un Conteneur Géré transaction serait mieux.
OriginalL'auteur Gordon Yorke
Ce pourrait être parce que vous n'avez pas commencé une transaction. Essayez:
Bien que je préfère ne pas faire le traitement des transactions de cette façon. Au lieu de cela, j'ai tendance à utiliser le Printemps déclarative des transactions, ce qui devrait ressembler à ceci:
lorsqu'il est configuré.
Edit: une Autre possibilité est un problème que j'ai eue avec EclipseLink où il n'était pas écrit tout à la base de données lorsque je courais dans un J2SE environnement (une application console pour charger des fichiers dans une base de données). Dans ce cas, j'ai dû explicitement
flush()
laEntityManager
pour obtenir tous les enregistrements écrits.Avec votre 1er exemple, j'ai l'exception suivante: Exception lors de l'inscription de l'utilisateur javax.ejb.EJBException: EJB Exception: java.lang.IllegalStateException: La méthode public abstract javax.la persistance.EntityTransaction javax.la persistance.L'EntityManager.getTransaction() ne peut pas être invoquée dans le cadre d'un JTA EntityManager.
OriginalL'auteur cletus