【问题标题】:EntityManager dont mergeEntityManager 不合并
【发布时间】:2017-09-28 07:59:58
【问题描述】:

测试junit添加了一个新角色而不是更新(它不更新)。我使用spring,hibernate,maven,Mysql。有人有想法吗?谢谢:

TestJunit.java:

.........
public class TestJunit {

@Test
public void UpdateRole() {
    InterfAdminMetier metier = (InterfAdminMetier) context
            .getBean("metier");
    Role r = metier.getRole("ROLE_Test");
    System.out.println("1 before update************************************"+r.getRoleName());
    r.setRoleName("ROLE_TestUpdate");
    metier.updateRole(r);
    System.out.println("2 after update************************************"+metier.getRole("ROLE_Test").getRoleName());
    assertTrue(metier.getRole("ROLE_TestUpdate").getRoleName().contentEquals("ROLE_TestUpdate"));

}
}

用户.java:

    ........
//import org.hibernate.mapping.Set;


/*classe JavaBean:les propriétes ne sont accessible que par les gettters et les setters
il faut definir un constructeur sans parametres si non il ne sera pas defini par defaut si nous deffinision un 
constructeur avec parametres*/
@Entity
@Table(name = "users")
public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "id")
    private String id;

    private String nom;
    private String prenom;
    private String mail;
    private String pw;

    /*
     * un utilisateur peut avoir plusieurs role comme l'admin qui a les roles
     * admin, biblio, enseignant, etud un role peut etre attribuer a plusieurs
     * utili comme roleEtudiant
     */


/*  @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "roles_users",  joinColumns = {
            @JoinColumn(name = "idUser", nullable = false, updatable = true) },
            inverseJoinColumns = { @JoinColumn(name = "roleName",
                    nullable = false, updatable = true) })
    private Set<Role> roles = new HashSet<Role>(0);*/


    @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
    @JoinTable(name = "roles_users", joinColumns = { @JoinColumn(name = "idUser", referencedColumnName = "id", nullable = false, updatable = true) }, inverseJoinColumns = { @JoinColumn(name = "roleName", referencedColumnName = "roleName", nullable = false, updatable = true) })
    private Set<Role> roles = new HashSet<Role>(0);
       ........................................
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }

    ..........................................

    public String getId() {
        return id;
    }

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

    public String getNom() {
        return nom;
    }

    public void setNom(String nom) {
        this.nom = nom;
    }

    public String getPrenom() {
        return prenom;
    }

    public void setPrenom(String prenom) {
        this.prenom = prenom;
    }

    public String getMail() {
        return mail;
    }

    public void setMail(String mail) {
        this.mail = mail;
    }

    public String getPw() {
        return pw;
    }

    public void setPw(String pw) {
        this.pw = pw;
    }

    public Collection<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    ...................................

}

角色.java:

        ............
    @Entity
    @Table(name = "roles")
    public class Role implements Serializable {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @Id
        @Column(name = "roleName")
        private String roleName;

        @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
        private Set<User> users = new HashSet<User>(0);

        /*
         * @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles") private
         * Collection<User> users;
         */

        public Role() {
            super();
            // TODO Auto-generated constructor stub
        }

        public Role(String roleName) {
            super();
            this.roleName = roleName;
        }

        public Collection<User> getUsers() {
            return users;
        }

        public void setUsers(Set<User> users) {
            this.users = users;
        }

        public String getRoleName() {
            return roleName;
        }

        public void setRoleName(String roleName) {
            this.roleName = roleName;
        }

    }

BiblioDaoImplementation.java:

    ...........
public class BiblioDaoImplementation implements InterfaBiblioDao {
    @PersistenceContext(unitName = "UP_Biblio")
    private EntityManager em;


//  ---------------------------------------user---------------------------------    
    @Override
    public String addUser(User user) {

        em.persist(user);

        return user.getId();
    }

    @Override
    public String removeUser(String id) {

        User user = getUser(id);
        em.remove(user);

        return user.getId();
    }

    @Override
    public String updateUser(User user) {

        em.merge(user);

        return user.getId();
    }

    @Override
    public User getUser(String Id) {

        return em.find(User.class, Id);
    }

    @Override
    public void attrubierRoleToUser(Role role, String id) {

        User u = em.find(User.class, id);

        u.getRoles().add(role);

    }

    @Override
    public List<User> listUsers() {

        Query req = em
                .createQuery("select user from User user");

        return req.getResultList();
    }

    @Override
    public List<User> listUserByRole(String roleName) {

        Query req = em
                .createQuery(" SELECT u FROM Role r JOIN r.users u  WHERE r.roleName=:x");

        req.setParameter("x", roleName);

        return req.getResultList();
    }

//  ---------------------------------------role---------------------------------
    @Override
    public String addRole(Role role) {

        em.persist(role);

        return role.getRoleName();
    }

    @Override
    public String removeRole(String roleName) {
        Role role = em.find(Role.class, roleName);
        em.remove(role);

        return roleName;
    }

    @Override
    public String updateRole(Role role) {

        em.merge(r);



        return role.getRoleName();
    }


    @Override
    public Role getRole(String roleName) {

        return em.find(Role.class, roleName);
    }

    @Override
    public List<Role> listRoles() {

        Query req = em.createQuery("select role from Role role");

        return req.getResultList();
    }
    }

persistence.xml:

        <?xml version="1.0" encoding="UTF-8"?>
    <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="UP_Biblio" transaction-type="RESOURCE_LOCAL">
           <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
          <property name="hibernate.show_sql" value="true"/>
          <property name="hibernate.hbm2ddl.auto" value="update"/>
          <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        </properties>
      </persistence-unit>
    </persistence>

applicationContext.xml:

        <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:s="http://www.springframework.org/schema/security"
        xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

      <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
      <property name="url" value="jdbc:mysql://localhost:3306/biblioissteg"></property>
      <property name="username" value="root"></property>
      <property name="password" value=""></property>
      </bean>


      <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
      <property name="defaultDataSource" ref="datasource"></property>
     <property name="persistenceXmlLocations">
        <list>
        <value>classpath*:META-INF/persistence.xml</value>
        </list>
    </property>
    </bean>


    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      <property name="persistenceUnitManager" ref="persistenceUnitManager"></property>
      <property name="persistenceUnitName" value="UP_Biblio"></property>
    </bean>


        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"></property>
        </bean>

        <tx:annotation-driven transaction-manager="transactionManager"/>
        <context:annotation-config></context:annotation-config>

       <bean id="dao" class="tn.issteg.biblio.dao.BiblioDaoImplementation"></bean>
       <bean id="metier" class="tn.issteg.biblio.metier.BiblioMetierImpl">
          <property name="dao" ref="dao"></property>
       </bean>

    </beans>

控制台: ...... 信息:org.springframework.security.config.http.DefaultFilterChainValidator - 检查登录 URL '/login' 是否可以通过您的配置访问 休眠:从角色role0_中选择role0_.roleName作为roleName2_0_ where role0_.roleName=? 1avant up************************************ROLE_Test 休眠:从角色role0_中选择role0_.roleName作为roleName2_0_ where role0_.roleName=? Hibernate:插入角色(roleName)值(?) 休眠:从角色role0_中选择role0_.roleName作为roleName2_0_ where role0_.roleName=? 2apres up************************************ ROLE_Test 休眠:从角色role0_中选择role0_.roleName作为roleName2_0_ where role0_.roleName=?

【问题讨论】:

    标签: spring hibernate jpa junit


    【解决方案1】:

    因为您正在更改角色名称,这是角色类的标识符,因此会创建一个新角色,如果您更改除标识符之外的任何内容,它将被更新

    【讨论】:

    • 我认为你说的是​​true,所以我必须在Role 类中添加另一个字段(idRole b> 并且将是 ID,没有其他方法可以进行更新吗?对于这种情况 (Role) 是可能的,但是如果我们想修改一个 userid ,那么这是不可能的!我认为这没有意义
    • 实际上选择标识符取决于你的逻辑、你的数据模型和你的业务模型......你认为它应该是什么标识符应该是 - 嗯 - 标识符,因此它不能改变对于同一个实体,任何可编辑字段都不能是标识符......所以如果您认为添加一个 ID 字段是合适的(因为您需要角色名称是可编辑的)然后去它......如果您认为用户 ID 应该是可编辑的,您需要选择另一个标识符 .. 这完全取决于您的逻辑 .. 希望对您有所帮助
    • 如果你认为答案是正确的,你可以优雅地接受它作为正确答案:)
    • 谢谢,“标识符,因此不能根据同一实体进行更改”,它可以被另一个实体修改吗?请解释这个或这个项目的文件
    【解决方案2】:

    尝试使用update 而不是merge

       public String updateRole(Role role) {
    
             em.update(role);
        return role.getRoleName();
         }
    

    【讨论】:

    • 谢谢,但 eclipse 不提供更新,当我输入它时,它告诉我一个错误,并建议对 em 进行强制转换.....
    • 问题是merge找不到要更新的对象,所以你能不能先测试一下getRole方法,看看它是否是绿色的
    • 在junit测试中我在更新前后调用了方法getRole,可以看到**console**(outpout):1-befort update************************************ROLE_Test Hibernate: select role0_.roleName as roleName6_0_ from roles role0_ where role0_.roleName=? Hibernate: select role0_.roleName as roleName6_0_ from roles role0_ where role0_.roleName=? 2-after update************************************ROLE_Test
    猜你喜欢
    • 2023-03-23
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2018-01-09
    相关资源
    最近更新 更多