【问题标题】:Entity manager not persisting class instance实体管理器没有持久化类实例
【发布时间】:2014-05-13 06:08:45
【问题描述】:

我有一个faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
    version="2.2">
    <managed-bean>
        <managed-bean-name>registerBean</managed-bean-name>
        <managed-bean-class>com.beans.RegisterBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
</faces-config>

User 类:

package model;

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


/**
 * The persistent class for the users database table.
 * 
 */
@Entity
@Table(name="users")
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable 
{
    private static final long serialVersionUID = 1L;

    @Id
    private int id;

    private String password;

    private String userName;

    public User() {
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUserName() {
        return this.userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

}

还有一个RegisterBean 类:

package com.beans;

import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.transaction.UserTransaction;

import model.User;

//see faces-config.xml to see annotations

public class RegisterBean 
{
    @PersistenceContext(unitName="user-unit", type=PersistenceContextType.EXTENDED) 
    private EntityManager em;

    private String name;
    private String password;
    private String passwordRepeat;

    public String getPasswordRepeat() 
    {
        return passwordRepeat;
    }


    public void setPasswordRepeat(final String passwordRepeat) 
    {
        this.passwordRepeat = passwordRepeat;
    }


    public String getName ()
    {
        return name;
    }


    public void setName (final String name)
    {
        this.name = name;
    }


    public String getPassword ()
    {
        return password;
    }


    public void setPassword (final String password)
    {
        this.password = password;
    }

    public void register()
    {
        //TODO: validate username and password
        User newUser = new User();
        newUser.setPassword(password);
        newUser.setUserName(name);
        //User foundUser = em.find(User.class, 22); //this actually finds the user with Id 22

        em.persist(newUser); //TODO: find out why this doesn't work.
    }
}

问题RegisterBeanregister()方法影响MySQL表,即em.persist()不会抛出任何异常,但是实体没有进入我的数据库。谁能帮帮我?

编辑:根据要求
持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="user-unit">
        <jta-data-source>java:jboss/datasources/DefaultDS</jta-data-source>
    </persistence-unit>
</persistence>

【问题讨论】:

  • 应该通过容器管理的持久性自动发生,但是您可以尝试通过调用 em.flush() 来结束 register 吗?
  • @mabi well 导致javax.servlet.ServletException: javax.persistence.TransactionRequiredException: no transaction is in progress javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
  • 看,persist() 调用只添加到内部缓存。它不关心交易。 您使用容器管理的持久性还是自己管理事务?
  • @mabi 从发布的代码中可以明显看出根本没有事务管理

标签: java mysql jsf javabeans entitymanager


【解决方案1】:

您正在 JSF 托管 bean 中使用扩展的持久性上下文。这意味着您没有活动的事务,并且您的所有 DML-s 都在排队​​而不是执行。

see

如果您与事务外的扩展持久性上下文进行交互,则插入、更新和删除将排队,直到您访问事务内的持久性上下文。这意味着您调用的任何 persist()、merge() 或 remove() 方法实际上不会导致 JDBC 执行,因此不会更新数据库,直到您手动调用 EntityManager.flush()。

【讨论】:

    【解决方案2】:

    在 Java EE 6 中,为了创建事务,您需要 EJB(容器管理事务)或自己管理事务边界(Bean 管理事务)。请参阅链接教程。

    最简单的方法是两种方法中的第一种:要实现它,只需将相关代码移动到@Stateless EJB 中(确保您的持久性上下文未扩展)

    RegisterBean

    public class RegisterBean {    
        @EJB MyService service;
    
        public void register() {
            //TODO: validate username and password
            User newUser = new User();
            newUser.setPassword(password);
            newUser.setUserName(name);
            service.create(newUser);
        }
    }
    

    我的服务

    @Stateless
    public class MyService {
        @PersistenceContext(unitName="user-unit") 
        private EntityManager em;
    
        public void create(User newUser) {
            em.persist(newUser);
        }
    }
    

    有用的链接

    【讨论】:

    • 请注意:无状态 EJB 不能具有扩展的持久性上下文
    • @gadget 你是对的,我没有看到扩展的持久性上下文。刚刚更正了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    相关资源
    最近更新 更多