EntityManager не удается создать экземпляр с использованием JPA / Hibernate, когда я добавляю аннотацию OneToMany - PullRequest
2 голосов
/ 22 декабря 2009

Мне трудно было создать экземпляр EntityManager, когда я добавляю столбец OneToMany к классу, в котором уже есть столбец OneToMany.

Прямо сейчас EducationInfo имеет OneToOne для пользователя, поскольку каждая строка будет уникальной для человека, но я хочу иметь возможность загружать всю информацию об образовании с указанным именем пользователя.

Я не изменяю файл orm.xml при добавлении столбца, я просто удаляю базу данных, чтобы ее можно было воссоздать.

class User {
  @Id
  @GeneratedValue(){val strategy = GenerationType.AUTO}
  var id : Int = _

  @Column{val nullable = false, val length=32}
  var firstName : String = ""
  var lastName : String = ""

  @Column{val nullable = false, val unique = true, val length = 30}
  var username : String = ""

  @OneToMany{val fetch = FetchType.EAGER, val cascade=Array(CascadeType.ALL)}
  var address : java.util.List[Address] = new java.util.ArrayList[Address]()

  @OneToMany{val fetch = FetchType.EAGER, val cascade=Array(CascadeType.ALL), val mappedBy="user"}
  var educationInfo : java.util.List[EducationInfo] = new java.util.ArrayList[EducationInfo]()

Если я не включаю последний столбец, тогда мой модульный тест работает нормально, но если я включаю его, то все мои модульные тесты не пройдены.

Вот класс, который он пытается использовать, и модульные тесты для этого класса работают нормально:

@Entity
@Table{val name="educationinfo"}
class EducationInfo {
  @Id
  @GeneratedValue(){val strategy = GenerationType.AUTO}
  var id : Long = _

  @Column{val nullable = false, val length = 100}
  var name : String = "";

  @OneToOne{val fetch = FetchType.EAGER, val cascade = Array(CascadeType.PERSIST, CascadeType.REMOVE)}
  @JoinColumn{val name = "educationinfo_address_fk", val nullable = false}
  var location : Address = _

  @ManyToOne{val fetch = FetchType.LAZY, val cascade=Array(CascadeType.PERSIST)}
  @JoinColumn{val name = "educationinfo_user_fk", val nullable = false}
  var user : User = _

  @Column{val nullable = false, val length = 100}
  var degree : String = ""

  @Temporal(TemporalType.DATE)
  @Column{val nullable = true}
  var startyear : Date = new Date()
  var endyear : Date = new Date()

  @Column{val nullable = true, val length = 1000}
  var description : String = ""
}

Мне также любопытно, есть ли какой-нибудь способ узнать, в чем заключается ошибка, которая препятствует созданию экземпляра EntityManager, но основная проблема заключается в том, что может вызывать проблему при добавлении этого столбца в User?

ОБНОВЛЕНИЕ:

Удалена деталь, которая была по ошибке.

ОБНОВЛЕНИЕ 2:

Я изменил столбец пользователя в образовательном объекте на @ManyToOne, и все мои модульные тесты не прошли.

Конец моего журнала ошибок таков:

15035 [main] INFO org.hibernate.cfg.SettingsFactory - Default entity-mode: pojo
15035 [main] INFO org.hibernate.cfg.SettingsFactory - Named query checking : enabled
15047 [main] INFO org.hibernate.impl.SessionFactoryImpl - building session factory
[PersistenceUnit: jpaweb] Unable to build EntityManagerFactory
[PersistenceUnit: jpaweb] Unable to build EntityManagerFactory

Тогда EntityManager равен нулю в каждом тесте, поэтому он терпит неудачу.

ОБНОВЛЕНИЕ 3:

Сущность Address не имеет внешних ключей ни к чему, так как она вызывается из нескольких сущностей.

Может ли эта проблема быть вызвана использованием Apache Derby в качестве базы данных?

К сожалению, я не получаю никаких сообщений об ошибках. Я запускаю это изнутри Maven, и хотя я удаляю базу данных каждый раз, когда я не могу сказать, что происходит, что это неправильно. @ManyToOne от EducationInfo -> User не вызывает никаких проблем, но @OneToMany -> EducationInfo от User.

ОБНОВЛЕНИЕ 4:

Я добавил mappedBy к сущности User, как было предложено. У меня было это в другом определении столбца, так как у меня есть пять определений, которые не будут работать, и я считаю, что они все по одной и той же причине, поэтому я просто тестирую с одним. К сожалению, это все еще приводит к тому, что EntiyManagerFactory не создается, поэтому все тесты не пройдены.

ФИНАЛЬНОЕ ОБНОВЛЕНИЕ:

Фактический случай был

не может одновременно извлечь несколько сумки

, поэтому я просто полностью удалил FetchType из EducationInfo, и проблема исчезла.

1 Ответ

3 голосов
/ 22 декабря 2009
Сопоставление

OneToMany на другой стороне ассоциации равно ManyToOne, оно не может быть OneToOne. Вот почему EntityManager терпит неудачу.

Это работает, когда вы удаляете последнюю строку из User, потому что тогда у вас останется только OneToMany до Address и, хотя здесь не показано, предположительно Address не имеет ссылки OneToOne до User.

Я не эксперт по Scala; в Java обычно выдается ошибка и выводится трассировка стека, когда EntityManager не удается инициализировать; сообщение об ошибке не всегда является наглядным, но обычно говорит о том, с каким отображением у него возникла проблема. Возможно, вам нужно настроить параметры ведения журнала, если вы не получили эту ошибку.

Я не совсем понял вашу модель:

Обычно пользователь должен иметь возможность есть несколько адресов, так что я ожидаю станет ManyToMany, но каждое использование также может иметь несколько случаев образовательная информация, поэтому необходимость ManyToOne.

Для меня это звучит как @OneToMany от User до Address и (если «использовать» означало «пользователь») как @OneToMany от User до EducationInfo.

Сейчас у EducationInfo есть OneToOne для пользователя, так как каждая строка будет быть уникальным для человека, но я хочу быть в состоянии загрузить все образование Информация предоставлена ​​имя пользователя.

Это противоречит вышеизложенному. Либо у вас может быть несколько EducationInfo на User, либо оно «уникально для человека».

...