gpt4 book ai didi

hibernate - JPA 和 Hibernate 不坚持我的对象让我发疯

转载 作者:行者123 更新时间:2023-11-29 12:22:21 25 4
gpt4 key购买 nike

我有一个现有的 java-JSF 项目,我被要求添加持久性,使用 JPA 和 Hibernate,当然还有 MVC。我使用 Postgres 作为 DBMS,使用 Netbeans 作为我的 IDE。我做了很多研究,结果比开始之前更加困惑,所以这是我到目前为止所得到的:

我的项目需要是一个工作列表网站,用户可以在其中注册然后申请工作机会。但我只是坚持注册用户。我的 View 有一个使用 JSF 构建的 register.xhtml 页面,我的模型包中有一个 User.java 类,我的 Controller 中还有一个 UserController bean。 register.xhtml 调用 UserController bean 中的 register() 方法,该方法应该保留 User 对象。

我已经像这样配置了我的 persistence.xml:

<persistence version="2.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_2_0.xsd">  
<persistence-unit name="TP5PU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<non-jta-data-source>tp5</non-jta-data-source>
<class>model.User</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="configLocation" value="WEB-INF/classes/hibernate.cfg.xml"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="postgres"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/pootp5"/>
</properties>
</persistence-unit>
</persistence>

我还创建了一个 PersistenceManager.java 类,它是一个单例并且里面还有一个单例 EntityManagerFactory:

import javax.persistence.*;

public class PersistenceManager {

private EntityManagerFactory emf = null;
private EntityManager em = null;
private static PersistenceManager instance = null;

private PersistenceManager(){
}

public static PersistenceManager getInstance() {
if (instance==null){
instance=new PersistenceManager();
}
return instance;
}

public EntityManagerFactory getEmf() {
if (emf == null){
this.setEmf(Persistence.createEntityManagerFactory("TP5PU"));
}
return emf;
}

public EntityManager getEm() {
this.setEm(this.getEmf().createEntityManager());
return em;
}

public void setEmf(EntityManagerFactory emf) {
this.emf = emf;
}


public void setEm(EntityManager em) {
this.em = em;
}
}

现在,我的 UserController bean 有这段代码:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import java.io.Serializable;
import javax.persistence.EntityTransaction;
import model.PersistenceManager;
import model.Usuario;

@ManagedBean (name="userController")
@SessionScoped
public class UserController implements Serializable{

private String username;
private String password;
private String name;
private String lastname;
private String resume;
private PersistenceManager pm;
private EntityTransaction tx;

public UserController() {
pm = PersistenceManager.getInstance();
tx = pm.getEm().getTransaction();
}


public String register() {
User user = new User(this.getUsername(), this.getPassword(), this.getName(), this.getLastname(), this.getResume());
try {
getPm().getEmf();
getTx().begin();
getPm().getEm().persist(user);
getTx().commit();
getPm().getEm().close();
return "registered";
}
catch (org.hibernate.exception.ConstraintViolationException e1){
if (getTx().isActive()){
getTx().rollback();}
getPm().getEm().close();
return "duplicateuser";
}
catch (Exception e2){
if (getTx().isActive()){
getTx().rollback();}
getPm().getEm().close();
return "registrationerror";
}
}

//all getters & setters
}

我所有的 User.java 类都有一堆属性和 getter/setter 方法:

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class User implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(updatable=false)
protected long userID;
@Column(unique=true)
private String username;
private String password;
private String name;
private String lastname;
private String resume;

//and all the getters & setters needed for each attribute.

register.xhtml 页面有一个注册表单(我没有在此处包括它,因为它只是一团糟,包含所有 i18n 键和其他东西)在按下“Register”按钮时调用 UserController bean:

如果 register() 方法返回“registered”,则说明存在将用户带到应用程序登录的导航规则。如果它返回“duplicateuser”,那么它会被带回 register.xhtml,如果它抛出不同的错误消息,它也会将用户带回 register.xhtml(是的,这些没有太多逻辑,我需要保持简单).

问题是,我创建了我的 User 表,但没有 User 保存在其中,我也没有收到任何错误消息、异常或任何东西。调试时,我在 UserController bean 中的 EntityTransaction 对象将事务显示为 beginning=true,然后 committed=true,因此一切似乎都正常。但是我去检查我的数据库并创建了表但是其中没有用户:(

此外,我想知道在将 PersistenceManager 作为单例并将所有持久性逻辑粘贴到 UserController bean 中时,我是否以正确的方式进行。如果有人可以指导我一点,我将非常感激!:)

最佳答案

每次调用您的 getEM() 方法都会创建一个新的 EntityManager。这意味着您用来启动事务的实体管理器与您随后调用的实体管理器不同 persist(user);在。因此事务已提交,但未绑定(bind)到包含您的更改的 EM。

使用静态 PM 来保存 EntityManagers 是一个坏主意,因为 EntityManagers 本身不是线程安全的。用于获取 EntityManager 可能很好,但是 register 和其他方法需要直接持有 entityManager 并在完成后关闭它。 PM 还应该有一个清理方法,可以在关闭或取消部署时关闭其工厂。

关于hibernate - JPA 和 Hibernate 不坚持我的对象让我发疯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13648098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com