Foreign Key Constraint Problem, Bug?
tvanbuskirk May 8, 2006 3:45 PMHi 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 ... }