JPA, @OneToMany, @ManyToOne нет JoinTable, ForiegnKey никогда не устанавливались?

У меня есть следующие два класса в oneToMany и ManyToOne

Родительский класс:

@Entity    
class ParentBean{

@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id_parent;

@Column( name = "NAME" )    
private String name;

@OneToMany( mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER )
private List<ChildBean> revisionList;
}

дочерний класс:

@Entity    
class ChildBean {

@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id_child;
private String name;

@ManyToOne( fetch = FetchType.EAGER, cascade = CascadeType.ALL )
@JoinColumn( name = "ID_PARENT", nullable = false )
private ParentBean parent;
}

Я использую следующий код для создания bean-компонентов:

ParentBean parent = new ParentBean();
parent.setName( "test parent");

List<ChildBean> revList = new ArrayList<>();

ChildBean child = new ChildBean();
child.setName( "test child" );

revList.add ( child );

parent.setRevisionList( revList );

Затем я использую это для записи структуры компонента в базу данных...

@PersistenceContext
private EntityManager em;

@Override
public void addDrawing( FtDrawing drawingIn )
{

    em.persist( drawingIn );

    em.flush();
}

Родительский компонент написан, но я получаю следующую ошибку, и дочерний компонент никогда не записывается

Вызвано: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: столбец «ID_PARENT» не может быть нулевым

Я посмотрел в Интернете и просмотрел несколько разных примеров, и все они кажутся такими же, как и то, что я делаю... Моя база данных - MySQL, и у меня есть два первичных ключа, для которых установлено значение auto_increment. Последняя вещь. Я не указал внешний ключ в дочерней таблице для обратной связи с родительской таблицей... это обязательно? Я использовал более старую версию спящего режима, и в этом не было необходимости...

Заранее спасибо за помощь


person cotfessi    schedule 29.06.2014    source источник
comment
Перед сохранением ChildBean необходимо установить его поле parent. Проблема в том, что когда вы добавляете дочерний элемент в родительский список, родительское поле дочернего элемента не устанавливается. Установите его перед сохранением (при каскадном сохранении родителя).   -  person Unda    schedule 29.06.2014


Ответы (1)


Чтобы заставить его работать, вы должны установить поле parent файла ChildBean. Если вы этого не сделаете, поле будет пустым, и ваш код говорит, что оно не может быть нулевым. Итак, вы должны сделать это:

ParentBean parent = new ParentBean();
parent.setName( "test parent");

List<ChildBean> revList = new ArrayList<>();

ChildBean child = new ChildBean();
child.setName( "test child" );

revList.add ( child );

child.setParent( parent ); // don't forget this.
parent.setRevisionList( revList );

Для удобства вы можете написать метод addChild в ParentBean, который сделает это автоматически, и тогда вам никогда не придется об этом беспокоиться:

public class ParentBean {
    /* ... */

    public void addChild(ChildBean child) {
        this.revisionList.add(child);
        child.setParent(this);
    }

    /* ... */
}

Затем просто назовите его вместо parent.getRevisionList().add(child).

Изменить: я думаю, что в вашем коде есть еще пара проблем.

  • Ваши ParentBean и ChildBean должны содержать аннотацию @Id вместо @GeneratedValue.
  • ИМО, требуется внешний ключ для родителя в дочерней таблице. Не вижу причин не ставить.
person Unda    schedule 29.06.2014