2

This one has had me stumped for several hours. It's related to my other question here:

JPA/hibernate - Cannot add or update a child row: a foreign key constraint fails - BUT record exists

I got rid of nearly all the code and narrowed down the problem. I have three very simple entities:

@Entity public class Building { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; public Building() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } } 

Other.java

@Entity public class Other { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @ManyToOne @JoinColumn(name = "building_id") private Building building; public Other() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Building getBuilding() { return building; } public void setBuilding(Building school) { this.building = school; } } 

Event.java

@Entity public class Event { @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; @ManyToOne @JoinColumn(name = "other_id") private Other other; public long getId() { return id; } public void setId(long id) { this.id = id; } public Other getOther() { return other; } public void setOther(Other other) { this.other = other; } } 

This will fail with a foreign key constraint violation:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`blah`.`event`, CONSTRAINT `FK403827A76D0546B` FOREIGN KEY (`other_id`) REFERENCES `Other` (`id`)) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 

NOW HERE'S THE REALLY BIZARRE PART!!!! If I do an eclipse refactor and rename the "Other" entity "Bob" it works perfectly fine. Just so we're on the same page, the Event entity will now look like this:

@Entity public class Event { @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; @ManyToOne @JoinColumn(name = "bob_id") private Bob bob; public long getId() { return id; } public void setId(long id) { this.id = id; } public Bob getBob() { return bob; } public void setBob(Bob bob) { this.bob = bob; } } 

And now it works perfectly fine. Can someone please explain this to a Hibernate newbie like myself? This really has me stumped. It fails when I persist a new Event to the database in my service layer:

@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) public void addEvent(Event event) throws ErrorCodeException, Exception { // not sure if I need to do this, still fails if I remove it event.setOther(otherDAO.getReferenceById(event.getOther().getId())); eventDAO.persist(event); } 

One further comment. Instead of renaming Other to Bob, I can also set the table name to lowercase:

@Entity @Table(name = "other") public class Other { 

This ALSO fixes it. But I cannot accept these solutions. I want to know why it's failing. I made a technology decision not to use Grails to avoid this type of "magic".

Here's the SQL hibernate logs:

// Initial database inserts Hibernate: insert into Building values ( ) Hibernate: insert into Other (building_id) values (?) // Insert which throws exception Hibernate: insert into Event (other_id) values (?) 2011-06-27 11:31:51 JDBCExceptionReporter [WARN] SQL Error: 1452, SQLState: 23000 2011-06-27 11:31:51 JDBCExceptionReporter [ERROR] Cannot add or update a child row: a foreign key constraint fails (`blah`.`event`, CONSTRAINT `FK403827A76D0546B` FOREIGN KEY (`other_id`) REFERENCES `Other` (`id`)) org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.ConstraintViolationException: could not insert: [com.blah.server.domain.Event]; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not insert: [com.blah.server.domain.Event] 
4
  • 1
    Which entity is mapped to the table blah? And I wonder if hibernate is generating a query with a mysql keyword as the name of one of the columns. Could you add the queries that hibernate generates? Commented Jun 27, 2011 at 15:29
  • blah is the database name. I added the queries to the initial post. thanks for your help! Commented Jun 27, 2011 at 15:34
  • I'm running mysql 5.1 on Mac OS X Commented Jun 27, 2011 at 16:10
  • I found the solution. It seems the combination of mac os x, hibernate, and mysql cause this problem. See: developmentality.wordpress.com/2011/05/23/… Commented Jun 27, 2011 at 17:23

1 Answer 1

2

UPDATE: I found the solution here:

http://developmentality.wordpress.com/2011/05/23/hibernate-mysql-mac-foreign-key-nightmares-a-painless-solution-to-a-painful-problem/

It seems the combination of mysql, hibernate, and mac os x cause this problem. As a solution, use a lowercase naming strategy.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.