8 Replies Latest reply on Feb 22, 2007 3:57 PM by micho

    relationship does not prevent from deleting referenced entit

    micho

      I thougtht, that the definition of a unidirectional relationship without cascading delet would prevent the Entities from deletion

      Example:
      unidirectional many-to-many relationship between user and usergroup.
      users know their usergroups,
      usergroups do not know their users

      It shold not be possible to delete a usergroup which is in an relationship to a (or many) user

      I coded like this, what have I done wrong?

      Thanks Micho

      @Entity
      public class Usergroup implements Serializable
      { private long mSid;
       private String mName;
      
       public BenutzerGruppe()
       { super(); }
      
       @Id @GeneratedValue(strategy=GenerationType.AUTO)
       public long getSid()
       { return mSid; }
      
       public void setSid(long sid)
       { mSid = sid; }
      
       public String getName()
       { return mName; }
      
       public void setName(String pName)
       { this.mName = pName; }
      }
      

      @Entity
      public class User implements Serializable
      { private long mSid;
       private String mName;
       private List<Usergroup> mUsergrouplist;
      
       public User()
       { super(); }
      
       public String getName()
       { return mName; }
      
       public void setName(String pName)
       { mName = pName;}
      
       @Id @GeneratedValue(strategy=GenerationType.AUTO)
       public long getSid()
       { return mSid; }
      
       public void setSid(long pSid)
       { mSid = pSid; }
      
       @ManyToMany
       ( targetEntity = Usergroup.class )
       public List<Usergroup> getUsergrouplist()
       { return mUsergrouplist; }
      
       public void setUsergrouplist(List<Usergroup> pUsergrouplist)
       { mBenutzerGruppeListe = pBenutzerGruppeListe; }
      }
      


        • 1. Re: relationship does not prevent from deleting referenced e
          micho

          jboss-4.0.4.GA_1 is used

          • 2. Re: relationship does not prevent from deleting referenced e
            onormann

            Try something like this:

            @ManyToMany( targetEntity = Usergroup.class, cascade={CascadeType.MERGE, CascadeType.REFRESH})
            


            Best regards

            • 3. Re: relationship does not prevent from deleting referenced e
              alexg79

              Have you checked whether the correct foreign keys are in place in the database? If not, have you tried to drop the tables and allow Hibernate (which I assume you're using) to generate the tables again?

              On a side note, a few non related tips for you:

              1. You don't need an explicit constructor if the sole constructor is public and has no arguments. Calling super() is useless if the class only extends java.lang.Object.
              2. When defining relationships, you don't need to specify targetEntity when using generics.
              3. You don't EVER have to specify strategy = GenerationType.AUTO, since it's the default anyway.
              4. Always use English for variable and method names. Makes your software more consistent and maintainable.

              • 4. Re: relationship does not prevent from deleting referenced e
                micho

                Thanks a lot for the help.
                In the DB there are no foreign keys.
                Inspecting the Database, I saw, that the tabletype is MyISAM whitch I think doenot support foreign keys.
                How can I tell Hibernate to create the tables with type innodb?

                I tried dropping the tables. The uniqueconstraint, which wasn´t working before now works correct, the referential integrity not.

                • 5. Re: relationship does not prevent from deleting referenced e
                  alexg79

                  You can instruct MySQL to create InnoDB tables by default.
                  Just put

                  default-table-type=innodb
                  

                  under [mysqld], and you're set.

                  • 6. Re: relationship does not prevent from deleting referenced e
                    micho

                    thanks a lot,

                    that works fine now, and with innodb tables the referential integritay is not violated.

                    But I´, not sure, how to act here correctly.
                    I catch two (identical?) runtimeexceptions - why two?

                    java.lang.RuntimeException: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=nbmicho/143, BranchQual=, localId=143] status=STATUS_NO_TRANSACTION; - nested throwable: (javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update)
                    java.lang.RuntimeException: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=nbmicho/143, BranchQual=, localId=143] status=STATUS_NO_TRANSACTION; - nested throwable: (javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update)


                    before two ERRORS one with a stacktrace are reported
                    ERROR [JDBCExceptionReporter] Cannot delete or update a parent row: a foreign key constraint fails (`test/benutzer_benutzergruppe`, CONSTRAINT `FKFB569FDA36A7B8DE` FOREIGN KEY (`benutzerGruppeListe_sid`) REFERENCES `benutzergruppe` (`sid`))
                    ERROR [AbstractFlushingEventListener] Could not synchronize database state with session org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update


                    • 7. Re: relationship does not prevent from deleting referenced e
                      micho

                      I try to detect the constraintviolation now via

                      catch (RuntimeException e)
                      { if (e.getCause().getCause().getCause().getClass().toString().equals("class org.hibernate.exception.ConstraintViolationException") )
                       { DO SOMETHING


                      is that OK?

                      But there are two things I don´t understand.
                      1) why are there two identical exceptions? Is that a problem?
                      2) I guarded the call of the remove request with a try-catch block, but the exception is not cougth in this catchblock
                      try
                      { em.remove(deleteBg);
                      }
                      catch (Exception e)
                      { logger.error("...


                      • 8. Re: relationship does not prevent from deleting referenced e
                        micho

                        for point 1, the double Exception, I detected, that only one exception was thrown.

                        the loggger.error produces double output,
                        logger.debug doesnot.

                        But I still don´t know, why this happens and wyh I can´t catch the exception when calling em.remove