4 Replies Latest reply on May 9, 2006 8:27 PM by tvanbuskirk

    Foreign Key Constraint Problem, Bug?

    tvanbuskirk

      Hi Everyone,

      I'm getting the following error when I'm trying to persist multiple entities in the same method. Does anyone know if I'm doing something wrong? I really appreciate your help on this one, I can't seem to figure it out. Thanks in advance!

      (sorry I had to change example to Dogs, I know it's boring :) )

      ERROR:

      WARN [JDBCExceptionReporter] SQL Error: 1452, SQLState 23000
      ERROR [JDBCExceptionReporter] Cannot add or update a child row: a foreign key constraint fails ('testdb/kennel_dogs', CONSTRAINT 'FK_KENNEL_DOGS_DOGS' FOREIGN KEY ('kennelID') REFERENCES 'kennel' ('kennelID'))
      


      Stateless Session Bean where I'm trying to persist Kennels and Dogs:
      
      @Stateless
      public class KennelBean implements KennelRemote
      {
       private static Logger logger = Logger.getLogger(KennelBean.class.getName());
      
       @PersistenceContext(unitName="mysqlUnit")
       protected EntityManager em;
      
       public void insertKennel(Kennel kennel)
       {
       KennelEntity kennelEntity= new KennelEntity(kennel.getName(),
       kennel.getType(),
       kennel.getDescription());
       logger.info("Inserting kennel\"" + kennel.getName() + "\" to server");
       em.persist(kennelEntity);
       logger.info("Kennel inserted successfully");
      
       logger.info("- Looping through dogs within this kennel.");
       for(Dog dog: kennel.getDogs())
       {
      
       DogsEntity dogsEntity =
       new DogsEntity(dog.getName(),
       dog.getDescription());
      
       logger.info("--- Current Dog = " + dog.getName());
      
       // If the dog is not in the database yet, add it.
       if(!em.contains(dogsEntity))
       {
       logger.info("--- The dog \"" + dog.getName() + "\" does not exist ... inserting ...");
       em.persist(dogsEntity);
       logger.info("--- " + dog.getName() + " has been inserted.");
       }
      
       logger.info("--- Adding (" + kennel.getName() + "," + dog.getName() + ") to kennel_dogs");
       KennelDogsEntity kennelDogsEntity =
       new KennelDogsEntity(kennelEntity,dogsEntity);
       
       em.persist(kennelDogsEntity);
      
       logger.info("--- Addition successful!");
      
       }
       }
       }
      
      


      OK, so the ERROR above pops up when I try to add em.persist(kennelDogsEntity). If I take that out, the kennelEntity and dogsEntity(s) are inputted correctly into the database.

      My thought when I created this method was that em.persist(kennelEntity) would create that new entry in the database (or in the persistence context, that would represent the database). However, looking at the error that I'm getting, it looks like it doesn't get persisted right away (if it did, then I would have no foreign key problem when I try to persist kennelDogsEntity

      Is it my misunderstanding of when entities are supposed to be synchronized with the database? Is it a bug? If it is my misunderstanding, how can I force that kennelEntity to be persisted to the database, so I can use it in it's child table (kennel_dogs) later in the method?

      For any skeptics out there that question my entity beans, here are my entities, minus the setters (b/c they're self-explainatory):

      @Entity
      @Table(name = "kennel")
      public class KennelEntity implements Serializable
      {
       private long kennelID;
       private String name;
       private KennelType kennelType;
       private String description;
      
       public KennelEntity() {}
      
       public KennelEntity(String name, KennelType kennelType, String description)
       {
       this.name = name;
       this.kennelType= kennelType;
       this.description = description;
       }
      
       public String getDescription()
       {
       return description;
       }
      
       public String getName()
       {
       return name;
       }
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       public long getKennelID()
       {
       return kennelID;
       }
      
       public KennelType getKennelType()
       {
       return kennelType;
       }
      
       ... setters
      }
      
      @Entity
      @Table(name = "dogs")
      public class DogsEntity implements Serializable
      {
       private long id;
       private String name;
       private String description;
      
      
       public DogsEntity() {}
      
      
       public DogsEntity(String name, String description)
       {
       this.name = name;
       this.description = description;
       }
      
      
       public String getDescription()
       {
       return description;
       }
      
       @Id
       @GeneratedValue(strategy=GenerationType.AUTO)
       @Column(name="dogID")
       public long getId()
       {
       return id;
       }
      
       public String getName()
       {
       return name;
       }
      
       .... setters ....
      }
      
      @Entity
      @Table(name = "kennel_dogs")
      public class KennelDogsEntity implements Serializable
      {
       private KennelEntity kennelD;
       private DogsEntity dogID;
      
       public KennelDogsEntity() {}
      
       public KennelDogsEntity(KennelEntity kennelID, DogsEntity dogID)
       {
       this.kennelID = kennelID;
       this.dogID= dogID;
       }
      
       @Id
       @ManyToOne(optional=false)
       @JoinColumn(name="dogID")
       public DogsEntity getDogID()
       {
       return dogID;
       }
      
       @Id
       @ManyToOne(optional=false)
       @JoinColumn(name="kennelID")
       public KennelEntity getKennelID()
       {
       return kennelID;
       }
      
       ... setters ...
      }
      


        • 1. Re: Foreign Key Constraint Problem, Bug?
          tvanbuskirk

          I have read through the hibernate doc on how the persistence context is stored and synchronized several times, but cannot find an answer. The main question is this:

          Can I persist a parent and its list of children in the same method?

          i.e.

          public void persistParent(Parent p)
          {
           ParentEntityBean pBean = new ParentEntityBean(p);
           em.persist(pBean);
          
           List<Child> children = p.getChildren();
           Child firstChild = children.get(0);
           ChildEntityBean cBean = new ChildEntityBean(firstChild);
           em.persist(cBean);
          
           ParentChildRelationEntityBean pcRelBean = new ParentChildRelationEntityBean(pBean,cBean);
           em.persist(pcRelBean);
          
          }
          


          I have also tried flushing and refreshing (as talked about in the Hibernate EntityManager docs).

          i.e.
          public void persistParent(Parent p)
          {
           ...
           em.persist(pBean);
           em.flush();
           em.refresh(pBean);
          
           ...
           em.persist(cBean);
           em.flush();
           em.refresh(cBean);
          
           ...
           em.persist(pcRelBean);
          }
          


          Finally, I've tried using my own transaction:

          public void persistParent(Parent p)
          {
           EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysqlUnit",new HashMap());
           EntityManager em = emf.createEntityManager();
           ...
           EntityTransaction t1 = em.getTransaction();
           t1.begin();
           em.persist(pBean);
           t1.commit();
          
           ...
           EntityTransaction t2 = em.getTransaction();
           t2.begin();
           em.persist(cBean);
           t2.commit();
          
           ...
           em.persist(pcRelBean);
          }
          


          If you can help me solve this problem, I would be eternally grateful. I admit I'm new new Hibernate, and maybe this is a trivial question, but I would really appreciate any time that you have into figuring this out.

          Thanks in advance!

          • 2. Re: Foreign Key Constraint Problem, Bug?

            Hello,

            Of course you can persist relations in one method.

            public void persistParent(Parent p)
            {
             ParentEntityBean pBean = new ParentEntityBean(p);
             em.persist(pBean);
            
             List<Child> children = p.getChildren();
             Child firstChild = children.get(0);
             ChildEntityBean cBean = new ChildEntityBean(firstChild);
             em.persist(cBean);
            
             ParentChildRelationEntityBean pcRelBean = new ParentChildRelationEntityBean(pBean,cBean);
             em.persist(pcRelBean);
            
            }
            


            I think you have problem there :
            
            @Entity
            @Table(name = "kennel_dogs")
            public class KennelDogsEntity implements Serializable
            {
             private KennelEntity kennelD;
             private DogsEntity dogID;
            
             public KennelDogsEntity() {}
            
             public KennelDogsEntity(KennelEntity kennelID, DogsEntity dogID)
             {
             this.kennelID = kennelID;
             this.dogID= dogID;
             }
            
             @Id
             @ManyToOne(optional=false)
            // @JoinColumn(name="dogID")
             @JoinColumn(name="dogID", insertable=false, updatable=false)
             public DogsEntity getDogID()
             {
             return dogID;
             }
            
             @Id
             @ManyToOne(optional=false)
            // @JoinColumn(name="kennelID")
             @JoinColumn(name="kennelID", insertable=false, updatable=false)
             public KennelEntity getKennelID()
             {
             return kennelID;
             }
            
             ... setters ...
            }
            
            


            I hope it would be useful.

            • 3. Re: Foreign Key Constraint Problem, Bug?
              tvanbuskirk

              Hello Cyril,

              Thank you very much for your reply! I've implemented the code you have suggested:

              ...
              @JoinColumn(name="dogID", insertable=false, updatable=false)
              ...
              @JoinColumn(name="kennelID", insertable=false, updatable=false)
              


              Unfortunately it still leaves me with the same error described above. Do you have any other thoughts on why I might be getting this foreign key constraint violation?

              Thanks again!

              • 4. Re: Foreign Key Constraint Problem, Bug?
                tvanbuskirk

                For anyone wondering, I found this post:

                http://www.jboss.com/index.html?module=bb&op=viewtopic&t=76605

                saying that Primary Foreign Keys are not supported yet. That was back in February 2006 so maybe they will be supported soon?? Please please please??