JPA/hibernate - Cannot add or update a child row:

2019-05-24 03:47发布

问题:

I'm having a strange problem. I have some records in the database:

Company

  • id = 1, Name = Microsoft
  • id = 2, Name = Sun

Now I have another entity, Event which has a foreign key reference to Company:

@Entity
public class Event {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @ManyToOne
    private Company company;
}

In my web service layer, I create an Event using a company ID passed as a URL param:

@GET
@Path("addEvent")
public String addEvent(@QueryParam("cid") long companyId) {
    Company alreadyInDB = new Company();
    alreadyInDB.setId(companyId);

    Event event = new Event();
    event.setCompany(alreadyInDB);
    eventService.addEvent(event);
}

This than calls the EventService. I originally was using the line of code commented out. But when that failed with the foreign key constraint failure, I added the code to ensure the Company record exists. Sure enough, the code prints out the proper ID. But it still fails with a foreign key constraint violation.

@Service("eventService")
public class EventService {

    @Autowired
    EventDAO eventDAO;

    @Autowired
    CompanyDAO companyDAO;

    @Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
    public void addEvent(Event event) throws Exception
    {
        System.out.println("Company ID: " + event.getCompany().getId());

        Company ensureRecordExists = companyDAO.findById(event.getCompany().getId());
        System.out.println("ensureRecordExists: " + ensureRecordExists.getId());
        event.setCompany(ensureRecordExists);
        //event.setCompany(companyDAO.getReferenceById(event.getCompany().getId()));
        eventDAO.persist(event);
    }
}

Here's the relevant part of the stacktrace:

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

Any idea what's going on? I can physically see the record exists in mysql workbench. I have no idea why it's failing. I thought it might have something to do with flushing the session or some transactional issue...? But I see the record...

回答1:

You have to mention the @JoinColumn

@ManyToOne
@JoinColumn(name = "company_id")
private Company company;

This is responsible for creating the company_id on the Event table.



回答2:

I narrowed the problem down and posted another question here:

JPA/Hibernate - Entity name seems to be important. If I rename to "Bob" works fine

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/

Due to the combination of mysql, hibernate, and mac os x, there's some issue where you have to use a lowercase naming strategy in hibernate. Hibernate by default uses a camel case naming strategy.