java – Eclipselink JPA,Oracle,Weblogic,Calling Persist不提
发布时间:2020-12-15 04:51:47 所属栏目:Java 来源:网络整理
导读:我刚开始看看 java持久性(目前使用eclipse的eclipselink默认提供程序).基本上只是创建一个对象并尝试将其持久化到db(Oracle).我的理解是,当方法返回时,默认事务性应该将新对象提交到数据库,但似乎没有发生任何事情.有任何想法吗? @Statelesspublic class Re
我刚开始看看
java持久性(目前使用eclipse的eclipselink默认提供程序).基本上只是创建一个对象并尝试将其持久化到db(Oracle).我的理解是,当方法返回时,默认事务性应该将新对象提交到数据库,但似乎没有发生任何事情.有任何想法吗?
@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> 实体类: @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; } } 此外,为了回复对此问题的回复,使用我列出的代码,日志显示执行提交(为简洁起见,删除了一些细节) [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,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 ... ... 但如果我在坚持之后添加’flush’,我会得到’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)',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 ... ... 解决方法
经过大量调查,包括尝试容器管理和用户管理的事务,似乎问题是事务类型被指定为RESOURCE_LOCAL.在这种情况下,以下规则适用:
* You must use the EntityManagerFactory to get an EntityManager * The resulting EntityManager instance is a PersistenceContext/Cache * An EntityManagerFactory can be injected via the @PersistenceUnit annotation only (not @PersistenceContext) * You are not allowed to use @PersistenceContext to refer to a unit of type RESOURCE_LOCAL * You must use the EntityTransaction API to begin/commit around every call to your EntityManger * Calling entityManagerFactory.createEntityManager() twice results in two separate EntityManager instances and therefor two separate PersistenceContexts/Caches. * It is almost never a good idea to have more than one instance of an EntityManager in use (don't create a second one unless you've destroyed the first) 在我的例子中,我需要使用manager工厂来访问entitymanager,并使用persistenceUnit而不是persistenceContext.以下代码工作得很好: @Stateless @TransactionManagement(TransactionManagementType.CONTAINER) public class RegisterUser implements RegisterUserLocal { @PersistenceUnit(unitName = "SCBCDEntities") private EntityManagerFactory factory; public void registerNewUser(String username,String password) { EntityManager entityManager = factory.createEntityManager(); EntityTransaction entityTransaction = entityManager.getTransaction(); entityTransaction.begin(); User user = new User(); user.setPassword(password); user.setUsername(username); entityManager.persist(user); entityTransaction.commit(); } } 有关配置事务和persistence.xml中的设置的其他信息,请访问:http://openejb.apache.org/3.0/jpa-concepts.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |