2014-11-11 4 views
1

Редактировать: Этот код действительно работает правильно. Проблема была не связана и была вызвана конфликтующей Entity, которая создавала ограничение внешнего ключа и мешала мне вставлять в таблицу DataFile.Нарушение ограничения внешнего ключа JPA

У меня возникли некоторые проблемы с некоторыми сопоставлениями JPA для простого отображения @OneToMany.

Я использую EclipseLink и DerbyDB.

@Entity(name = "study2") 
@Access(AccessType.FIELD) 
public class Study2 extends EntityBaseItem { 

private List<DataFile> datafiles = new ArrayList<DataFile>(); 

public Study2() { } 

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 
@JoinColumn(name="STUDY_ID", referencedColumnName = "ID") 
@Access(AccessType.PROPERTY) 
public List<DataFile> getDatafiles() { 
    return this.datafiles; 
} 

public void setDatafiles(List<DataFile> dfList) { 
    this.datafiles = dfList; 
} 

DataFile.java

@Entity(name = "DataFile") 
public class DataFile extends EntityBaseItem<DataFile> { 
    private String filename; 
    private long filesize; 
    private String fileStatus; 
    private String fileType; 
    private String fileSubType; 

    public DataFile() { } 
} 

Это мой EntityBaseItem.java где @Id проживает:

@MappedSuperclass 
public abstract class EntityBaseItem { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    protected Integer id; 

    protected EntityBaseItem() {} 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 0; 
     hash += (this.getId() != null ? this.getId().hashCode() : 0); 

     return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
     if (this == object) 
      return true; 
     if (object == null) 
      return false; 
     if (getClass() != object.getClass()) 
      return false; 

     EntityBaseItem other = (EntityBaseItem)object; 

     if (this.getId() != other.getId() && (this.getId() == null || !this.id.equals(other.id))){ 
      return false; 
     } 

     return true; 
    } 
} 

Проблема заключается в том, что когда я создаю объект Study2 с некоторыми объектами DataFile и попытайтесь сохранить его в моей БД, тогда я получу ошибку

UPDATE on table 'DATAFILE' caused a violation of foreign key constraint 'DATAFILE_STUDY_ID' for key

Если изменить аннотацию на getDataFiles() и удалить @JoinColumn (смотрите ниже), то отображение работает, однако он создает присоединиться к столу и я на самом деле, а просто объединение столбец в таблице DataFile:

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 
@Access(AccessType.PROPERTY) 
public List<DataFile> getDatafiles() { 
    return this.datafiles; 
} 

Я предполагаю, что это вниз с моим @Id в EntityBaseItem, как когда я извлекал, что и добавил @Id в Study2 классе, то он работал, как и следовало ожидать, однако, должно быть каким-то образом сохранить @Id в EntityBaseItem и до сих пор используют a @JoinColumn? У меня не было никаких проблем в другом месте моего кода, и у меня есть различные другие сопоставления, которые не так просты, как эта.

Я знаю, что означает ошибка, однако я не знаю, почему это происходит. Для меня я ожидаю, что мой код будет работать и автоматически каскадирует DataFiles с новым идентификатором для каждого.

Вот код, который на самом деле вызывает ошибку быть выброшена:

Study2 testStudy = new Study2(); 
// set some datafiles etc. 

EntityManager em = getEM(); // gives me EntityManager 
em.getTransaction().begin(); 
em.persist(testStudy); 
em.getTransaction().commit(); 

я упростил его вниз к тому, что для тестирования, бросает ошибку на .commit(), а затем он откатывает фиксацию.

+0

Ur отображение является неправильным. Предоставление @JoinColumn в списке невозможно, говоря, что класс Study2 содержит много ключей таблицы DataList в одной строке –

+0

@ShoaibChikate Если это так, то что это должно быть, если не List? – james4563

+0

Я добавил ответ. Пожалуйста, проверьте –

ответ

0

Меняйте отображения

public class Study2(){ 

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true,mappedBy="study2") 
@Access(AccessType.PROPERTY) 
public List<DataFile> getDatafiles() { 
    return this.datafiles; 
} 
} 

Здесь мы говорим, что DataFile является mappedBy "study2" в классе DataFile и Study2 имеет JoinColumn. И Study2 является обратной стороной отношений и не будет обновлять отношения, когда он будет обновляться.

Добавить одно поле Study2 в DataFile, я дал отображение на field.You можно изменить, что

@ManyToOne 
    @JoinColumn(name="STUDY_ID", referencedColumnName = "ID") 
    private Study2 study2; 

Он утверждает, что многие DataFile присутствуют в классе один Study2

+0

Это просто неправильно. JoinColumn в однонаправленной ассоциации OneToMany отлично работает. См. Https://docs.oracle.com/javaee/6/api/javax/persistence/JoinColumn.html –

+0

Да, это нормально, если только у нас нет JoinTable. OP не имеет таблицы соединений. –

+0

Нет. Еще раз прочтите javadoc. В нем говорится «использование сопоставления внешнего ключа». В нем также говорится: «колонка соединения находится в таблице для заказа». Чтобы сопоставить ассоциацию с таблицей соединений, вы используете JoinTable. Чтобы сопоставить ассоциацию со столбцом объединения, вы используете JoinColumn. Разве это не логично? –

Смежные вопросы