【问题标题】:Cannot delete or update a parent row: a foreign key constraint fails (hibernate xml mapping)无法删除或更新父行:外键约束失败(休眠 xml 映射)
【发布时间】:2014-02-18 11:13:20
【问题描述】:

我想删除用户所属的所有组,但目前无法使用。我认为映射 User.hbm.xml 或 Group.hbm.xml 级别缺少一些东西,但我不知道。错误是 “无法删除或更新父行:外键约束失败 (sharedmap.groupe, CONSTRAINT FK_gq7win10rtxufsxu1n5istm2p FOREIGN KEY (user_id) REFERENCES user (id))”

以下是相关的类和文件 xml:

User.java

public class User {

    /** Attributs */ 


    @XmlTransient
    private Set<Group> proprietaire;

    /** Constructeur */ 
    public User() {
    }

    public User(String telephone, String pseudo, String email) {
        super();
        this.pseudo = pseudo;
        this.telephone = telephone;
        this.email = email;
    }


    public Set<Group> getProprietaire() {
        return proprietaire;
    }

    public void setProprietaire(Set<Group> proprietaire) {
        this.proprietaire = proprietaire;
    }

    ...

}

UserDao

public class UserDao {

    private static SessionFactory sessionFactory = SessionConfiguration.getFactory();

    /**
     * Method to ADD a user in the database
     * 
     * @param user
     * @return user_id
     */
    public static Integer addUser(User user) {
        Integer userID = null;
        Session session = sessionFactory.openSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            userID = (Integer) session.save(user);          
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
        return userID;
    }

    /**
     * 
     * Method to DELETE a user from the records
     * 
     * @param telephone
     */
    public static void deleteUser(String telephone) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        String query = "select u from User u where u.telephone = :telephone";
        User user = (User) session.createQuery(query)
                .setString("telephone", telephone).uniqueResult();
        try {
            tx = session.beginTransaction();
            session.delete(user);
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

User.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name="modele.User" table="user">
      <meta attribute="class-description">
         This class contains the user detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <property name="pseudo" column="pseudo" type="string"/>
      <property name="telephone" column="telephone" type="string" not-null="true" unique="true"/>
      <property name="email" column="email" type="string"/>

      <!--  Mapping Set<Demande> demandes -->
      <set name="demandes" cascade="save-update,delete" lazy="false">
         <key column="demandeur_id"/>        
         <one-to-many class="modele.Demande"/>
      </set>

      <!--  Mapping Set<Invitation> aInvite -->
      <set name="aInvite" cascade="save-update,delete" lazy="false">
         <key column="inviteur_id"/>
         <one-to-many class="modele.Invitation"/>
      </set>

      <set name="notifications" cascade="save-update,delete" lazy="false">
         <key column="user_id"/>
         <one-to-many class="modele.Notification"/>
      </set>


      <set name="groups"  table="participation" lazy="false" inverse="true">
         <key column="user_id"/>
         <many-to-many column="group_id" class="modele.Group"/>
      </set>

     <!--  Mapping Set<Group> proprietaire -->
      <set name="proprietaire" cascade="save-update,delete" lazy="false">
         <key column="user_id"/>
         <one-to-many class="modele.Group"/>
      </set>      

   </class>
</hibernate-mapping>

Group.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
 "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 

<hibernate-mapping>
   <class name="modele.Group" table="groupe">
      <meta attribute="class-description">
         This class contains the publicEvent detail. 
      </meta>
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <property name="description" column="description" type="string"/>
      <property name="hashtag" column="hashtag" type="string"/>
      <property name="password" column="password" type="string"/>
      <!--  Mapping ArrayList<Marqueur> marqueurs -->

      <set name="marqueurs" cascade="save-update,delete" lazy="false">
         <key column="group_id"/>
         <one-to-many class="modele.Marqueur"/>
      </set>
      <!--  Mapping Set<Invitation> invitations -->
      <set name="invitations" cascade="save-update,delete" lazy="false">
         <key column="group_id"/>
         <one-to-many class="modele.Invitation"/>
      </set>

      <!--  Mapping Set<Demande> demandes -->
      <set name="demandes" cascade="save-update,delete" lazy="false">
         <key column="group_id"/>
         <one-to-many class="modele.Demande"/>
      </set>

      <!--  Mapping User proprietaire -->
      <many-to-one name="proprietaire" class="modele.User" column="user_id" not-null="true"/>

      <!--  Mapping ArrayList<User> invites -->
      <set name="invites" table="participation" lazy="false">
         <key column="group_id"/>
         <many-to-many column="user_id" class="modele.User"/>
      </set>

   </class>
</hibernate-mapping>

UserDaoTest.java

public class UserDaoTest {

    private final String tel = "0601020304";
    private final String pseudo = "pseudo";
    private final String pseudoModified = "pseudo2";
    private final String email = "email@email.com";

    @Test
    public void addUserTest(){

        User initialUser = new User(tel, pseudo, email);

        // Add user in database
        UserDao.addUser(initialUser);

        User addedUser = UserDao.getUser(tel);

        // Add Group in User
        Group group = new Group();
        group.setDescription("description");
        group.setHashtag("hashtag");
        group.setPassword("password");
        //Set group proprietaire
        group.setProprietaire(addedUser);               

        //Add group in database
        GroupDao.addGroup(group);

        // Add Group in User
        Set<Group> groups = new HashSet<Group>();
        groups.add(group);
        addedUser.setGroups(groups);

        Assert.assertEquals(addedUser.getTelephone(), initialUser.getTelephone());
        Assert.assertEquals(addedUser.getPseudo(), initialUser.getPseudo());
        Assert.assertEquals(addedUser.getEmail(), initialUser.getEmail());
    }


    @Test
    public void deleteUserTest(){
        User user = UserDao.getUser(tel);

        UserDao.deleteUser(user.getTelephone());

        List<User> listUsers = UserDao.listUser();

        Assert.assertFalse(listUsers.contains(user));
    }
}

【问题讨论】:

  • 要理解的代码太多了,能否请您将其缩减为所需的内容。
  • 我删除了我的部分代码,并将错误跟踪放在我的问题中

标签: hibernate hibernate-mapping


【解决方案1】:

请尝试将 inverse=true 添加到用户文件集名称中,同时使用 cascade=all",delete-orphan

删除用户时删除组。另外请注意如何在 Hibernate 中删除用户:

必须在删除用户之前刷新会话。
必须从所有活动会话和二级缓存中逐出链接到您的用户的所有组。

【讨论】:

  • 这个答案几乎无法理解。 “对用户文件集名称也具有专有性”是什么意思?
猜你喜欢
  • 2016-03-08
  • 2017-06-11
  • 1970-01-01
  • 2019-05-25
  • 2014-11-11
  • 2018-05-12
  • 2017-09-15
  • 1970-01-01
相关资源
最近更新 更多