mw8*_*w88 3 java hibernate jpa jta
我是hibernate的新手,我希望它通过JNDI使用来自应用服务器的数据库连接.
奇怪的是,它在数据库中创建了我的表,但它没有保存实体.看起来,它没有提交.
有人遇到类似hibernate的问题吗?
这是一个小测试servlet:
public class WriteTest extends HttpServlet
{
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
/*try
{
User user = new User("Hans", "Maulwurf", "hans.maulwurf@test.de");
InitialContext ctx = new InitialContext();
UserFacadeBean bean = (UserFacadeBean) ctx.lookup("ejb/UserFacadeBeanService");
bean.persist(user);
}
catch (NamingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}*/
EntityManager em = JpaUtil.getEntityManagerFactory().createEntityManager();
//em.getTransaction().begin();
System.out.println("Begin transfer");
User user = new User("Hans", "Maulwurf", "hans.maulwurf@test.de");
Adress adress = new Adress("Deppenstraße 3","Deppingen");
//user.setAddress(adress);
System.out.println("Save User 'Hans Maulwurf'");
em.persist(user);
//em.persist(adress);
//em.getTransaction().commit();
em.close();
System.out.println("Everything went better than expected!");
}
}
Run Code Online (Sandbox Code Playgroud)
这是小助手级:
public class JpaUtil
{
private static final EntityManagerFactory emf;
static
{
try
{
System.out.println("Initialize EntityManagerFactory...");
emf = Persistence.createEntityManagerFactory("testPU");
}
catch (Throwable ex)
{
System.err.println("Initial EntityManagerFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static EntityManagerFactory getEntityManagerFactory()
{
return emf;
}
}
Run Code Online (Sandbox Code Playgroud)
我的用户对象:
@Entity
@Table(name = "T_UserJpa")
public class User implements Serializable
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Embedded
@AttributeOverrides(
{
@AttributeOverride(name = "street", column =
@Column(name = "user_street")),
@AttributeOverride(name = "city", column =
@Column(name = "user_city", length = 50))
})
private Adress adress;
private String firstname;
private String lastname;
private String email;
public User()
{
}
public User(String firstname, String lastname, String email)
{
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
}
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public Adress getAddress()
{
return adress;
}
public void setAddress(Adress adress)
{
this.adress = adress;
}
public String getFirstname()
{
return firstname;
}
public void setFirstname(String firstname)
{
this.firstname = firstname;
}
public String getLastname()
{
return lastname;
}
public void setLastname(String lastname)
{
this.lastname = lastname;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof User))
{
return false;
}
final User user = (User) obj;
return !(email != null ? !email.equals(user.email) : user.email != null);
}
@Override
public int hashCode()
{
return 29 * (email != null ? email.hashCode() : 0);
}
}
Run Code Online (Sandbox Code Playgroud)
我的persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="testPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/testdb</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.autocommit" value="true"/>
</properties>
</persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)
编辑:我忘了提到,我已经使用了这个帖子中提供的信息:在Glassfish服务器上配置Hibernate JPA 2.0的学习资源
在应用程序服务器中,您可以管理容器EntityManager(也称为持久性上下文)或管理应用程序EntityManager.在这两种情况下,您都必须将持久性上下文与作为JTA事务或纯JDBC事务的事务关联.
关于你手头的问题,应该考虑以下几点:
persistence.xml文件表明您打算使用JTA数据源,因此使用JTA事务来执行事务性工作.JpaUtil类负责创建应用程序管理的EntityManager实例.根据上述两个语句以及应用程序演示的行为,您的EntityManager实例似乎与JTA事务无关.因此,在持久化上下文中进行的任何更改都不会刷新到数据库.这仅仅是因为JPA提供者将依赖JTA事务和登记资源来执行事务性工作; 如果没有找到,则不会进行任何工作(与资源本地事务的情况不同,其中连接池和资源登记由JPA提供者本身执行).
因此,EntityManager在执行对实体的任何更改之前,必须将或持久性上下文与活动事务关联,以便可以将对持久性上下文中的实体所做的所有更改刷新到数据库.要解决您的问题,您必须:
开始新的JTA交易.您可以选择容器管理的事务或应用程序管理的事务.
应用程序或Bean管理的事务由应用程序本身管理,而不是由容器管理.虽然这可能看起来适合您的情况,但请注意您现在负责交易管理; 通常这种策略会导致错误,并且通常情况下,开发人员并不了解它,结果通常认为它在大多数项目中都是不好的做法.如果您希望使用Bean托管事务,则需要使用UserTransactionAPI类启动事务,如下所示:
public class WriteTest extends HttpServlet
{
@Resource
UserTransaction tx; // a UserTransaction reference is injected like a any other resource. It can also be looked up from JNDI.
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
...
tx.begin(); // Start a new JTA BMT
EntityManager em = JpaUtil.getEntityManagerFactory().createEntityManager();
...
User user = new User("Hans", "Maulwurf", "hans.maulwurf@test.de");
Adress adress = new Adress("Deppenstraße 3","Deppingen");
//user.setAddress(adress);
em.persist(user);
em.close();
...
tx.commit(); // Commit the JTA BMT
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码并不完全适合生产.例如,它不执行任何异常处理,也不会在应用程序失败时显式回滚更改.
EntityManager如果该实例EntityManager尚未与JTA事务关联,则将该实例与JTA事务连接.如果首先启动JTA事务(在上面的涉及Bean管理事务的示例中完成),则不需要这样做,但如果您EntityManager使用JpaUtil类创建第一个事务,然后稍后启动事务,则必须使用该EntityManager.joinTransaction()方法加入JTA事务的持久化上下文.很明显,任何从与事务无关的持久化上下文中刷新的更改都将被忽略.
| 归档时间: |
|
| 查看次数: |
12002 次 |
| 最近记录: |