JPA / Hibernate - имя сущности, похоже, важно. Если я переименую в "Боб", то работает нормально - PullRequest
2 голосов
/ 27 июня 2011

Это заставило меня остаться в тупике на несколько часов.Это связано с моим другим вопросом здесь:

JPA / hibernate - Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется - НО запись существует

Я избавилсяпочти весь код и сузили проблему.У меня есть три очень простых объекта:

@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;
    }
}

Это не удастся с нарушением ограничения внешнего ключа:

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)

СЕЙЧАС ЗДЕСЬ ДЕЙСТВИТЕЛЬНО ЧУВСТВЕННАЯ ЧАСТЬ !!!!Если я сделаю рефактор затмения и переименую «Другой» объект в «Боб», он будет работать отлично.Точно так же мы находимся на той же странице, сущность Event теперь будет выглядеть так:

@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;
    }
}

И теперь она работает отлично.Может кто-нибудь объяснить это новичку Hibernate, как я?Это действительно поставило меня в тупик.Сбой, когда я сохраняю новое событие в базе данных на моем уровне обслуживания:

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

Еще один комментарий.Вместо того, чтобы переименовать Другое в Боба, я также могу установить имя таблицы в нижний регистр:

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

Это также исправляет это.Но я не могу принять эти решения.Я хочу знать, почему это не удается.Я принял технологическое решение не использовать Grails, чтобы избежать этого типа «магии».

Вот журналы спящего режима SQL:

// 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]

1 Ответ

2 голосов
/ 28 июня 2011

ОБНОВЛЕНИЕ: Я нашел решение здесь:

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 вызывает эту проблему. В качестве решения используйте строчную стратегию именования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...