JPA /休眠 - 无法添加或更新子行:外键约束失败 - 但记录存在 [英] JPA/hibernate - Cannot add or update a child row: a foreign key constraint fails - BUT record exists

查看:417
本文介绍了JPA /休眠 - 无法添加或更新子行:外键约束失败 - 但记录存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题。我在数据库中有一些记录:

公司


  • id = 1, Name = Microsoft

  • id = 2,Name = Sun
    $ b

    现在我有另一个实体,有公司外键引用的事件:

      @Entity 
    公共类事件{

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

    @ManyToOne
    私人公司公司;



    $ b $ p
    $ b在我的web服务层中,我使用一个公司ID一个URL参数:

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

    事件事件=新事件();
    event.setCompany(alreadyInDB);
    eventService.addEvent(event);
    }

    这比调用EventService。我原来是用这行代码注释掉的。但是,当外键约束失败失败时,我添加了代码以确保公司记录存在。当然,代码打印出正确的ID。但它仍然失败,违反外键约束。

      @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());

    公司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);




    $ p $这是stacktrace的相关部分:

     原因:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:无法添加或更新子行:外键约束失败``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)

    有什么想法发生了什么?我可以在物理上看到mysql workbench中存在的记录。我不知道为什么它失败。我认为这可能有冲突会议或一些交易问题...?但我看到记录...

    解决方案

    我缩小了问题的范围,并在此发布了另一个问题:



    我在这里找到了解决方案:

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



    由于mysql,hibernate和mac os x的组合,有一些问题需要在hibernate中使用小写的命名策略。 Hibernate默认使用骆驼命名策略。


    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...

    解决方案

    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.

    这篇关于JPA /休眠 - 无法添加或更新子行:外键约束失败 - 但记录存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆