EntityManager не удается создать экземпляр с использованием JPA / Hibernate, когда я добавляю аннотацию OneToMany
-
20-09-2019 - |
Вопрос
Я боролся с невозможностью создать экземпляр 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:
Я изменил столбец user в education entity на @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 имеет значение null в каждом тесте, поэтому он завершается неудачей.
ОБНОВЛЕНИЕ 3:
Тот самый Address
сущность не имеет внешних ключей ни к чему, так как она вызывается из нескольких сущностей.
Может ли эта проблема быть вызвана использованием Apache Derby в качестве базы данных?
К сожалению, я не получаю никакого сообщения об ошибке.Я запускаю это из maven, и хотя я каждый раз удаляю базу данных, я не могу сказать, что происходит не так.@ManyToOne из EducationInfo -> User не вызывает никаких проблем, но @OneToMany -> EducationInfo от User вызывает.
ОБНОВЛЕНИЕ 4:
Я добавил mappedBy к объекту User, как было предложено.У меня было это в другом определении столбца, поскольку у меня есть пять определений, которые не будут работать, и я полагаю, что все они по одной и той же причине, поэтому я просто тестирую с одним.К сожалению, это по-прежнему приводит к тому, что EntiyManagerFactory не создается, поэтому все тесты завершаются неудачей.
ОКОНЧАТЕЛЬНОЕ ОБНОВЛЕНИЕ:
Фактический случай был таков
невозможно одновременно получить несколько Сумки
поэтому я просто полностью удалил FetchType из EducationInfo, и проблема исчезла.
Решение
OneToMany
отображение дополнения на другой стороне ассоциации является ManyToOne
, это не могу быть OneToOne
.Вот что вызывает EntityManager
потерпеть неудачу.
Это работает, когда вы удаляете последнюю строку из User
потому что тогда у тебя остается только OneToMany
Для Address
и, хотя здесь это не показано, предположительно Address
не имеет OneToOne
ссылка на User
.
Я не специалист по Scala;в Java вы обычно получаете сообщение об ошибке и выводите трассировку стека, когда EntityManager
не удается инициализировать;сообщение об ошибке не всегда носит исключительно описательный характер, но обычно в нем говорится, с каким отображением возникла проблема.Возможно, вам нужно изменить настройки ведения журнала, если вы не получаете эту ошибку.
Я не совсем понял вашу модель:
В принципе, пользователь должен иметь возможность иметь несколько адресов, поэтому я ожидаю, что это станет ManyToMany, но каждое использование также может иметь несколько экземпляров образовательной информации, поэтому необходимость в Много кого.
Это звучит как @OneToMany из User
Для Address
для меня и (если "использовать" означало "пользователь") как @OneToMany из User
Для EducationInfo
.
Прямо сейчас в EducationInfo есть OneToOne для пользователя, поскольку каждая строка будет уникальной для человека, но я хочу иметь возможность загружать всю информацию об образовании с указанием имени пользователя.
Это противоречит вышесказанному.Либо у вас может быть несколько EducationInfo
за User
или это "уникально для каждого человека".