当我添加 OneToMany 注释时,EntityManager 无法使用 JPA/Hibernate 实例化
当我将 OneToMany
列添加到已经具有 OneToMany
列的类时,我一直在努力解决无法实例化 EntityManager 的问题。
现在,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 实例化的错误是什么,但主要问题当我将此列添加到用户时,可能会导致问题的原因是什么?
更新:
删除了错误的部分。
更新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在每个测试中都是null,所以它失败了。
更新3:
Address
实体没有任何外键,因为它是从多个实体调用的。
这个问题是否是由于使用 Apache Derby 作为数据库引起的?
不幸的是我没有收到任何错误消息。我从 Maven 中运行它,虽然每次我都删除数据库,但我无法判断发生了什么错误。来自 EducationInfo 的 @ManyToOne ->用户不会造成任何问题,但@OneToMany ->来自用户的 EducationInfo 确实如此。
更新4:
我按照建议向用户实体添加了mappedBy。我在另一列定义中也有这个定义,因为我有五个定义不起作用,而且我相信它们都是出于相同的原因,所以我只用一个进行测试。不幸的是,它仍然导致 EntiyManagerFactory 未构建,因此所有测试都失败。
最终更新:
实际情况是
无法同时获取多个 袋子
我只是从 EducationInfo 中完全删除了 FetchType,问题就消失了。
I have been struggling with not being able to have the EntityManager be instantiated when I add a OneToMany
column to a class that already has a OneToMany
column.
Right now the EducationInfo
has a OneToOne
to user, since each row will be unique to a person, but I want to be able to load all the education information given a username.
I am not changing the orm.xml file when I add the column, I just drop the database so it can be recreated.
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]()
If I don't include the last column then my unit test works fine, but if I include this then all my unit tests fail.
Here is the class it is trying to use, and the unit tests for this class works fine:
@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 = ""
}
I am also curious if there is some way to know what the error is that prevents the EntityManager from being instantiated, but the main problem is what may be causing a problem when I add this column to User?
UPDATE:
Removed a part that was in error.
UPDATE 2:
I changed the user column in the education entity to be @ManyToOne
and all my unit tests failed.
The end of my error log is this:
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
Then EntityManager is null in every test, so it fails.
UPDATE 3:
The Address
entity has no foreign keys to anything, as it is called from several entities.
Could this problem be caused by using Apache Derby as the database?
Unfortunately I don't get any error message. I run this from within maven, and though I delete the database each time I can't tell what it happening that is wrong. The @ManyToOne from EducationInfo -> User doesn't cause any problems, but @OneToMany -> EducationInfo from User does.
UPDATE 4:
I added a mappedBy to the User entity as suggested. I had that in another column definition, as I have five definitions that won't work, and I believe they are all for the same reason, so I am just testing with one. Unfortunately it still leads to the EntiyManagerFactory not being built so all the tests fail.
FINAL UPDATE:
The actual case was
cannot simultaneously fetch multiple
bags
so I just removed the FetchType completely from EducationInfo and the problem went away.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
OneToMany
关联另一侧的补映射是ManyToOne
,它不能是OneToOne
。这就是导致 EntityManager 失败的原因。当您从
User
中删除最后一行时,它会起作用,因为这样您就只剩下OneToMany
到Address
,尽管此处未显示,但大概Address
没有指向User
的OneToOne
链接。我不是 Scala 专家;我不是 Scala 专家。在 Java 中,当 EntityManager 初始化失败时,您通常会收到错误并打印堆栈跟踪;错误消息并不总是具有很强的描述性,但通常会说明它的映射有问题。如果您没有收到该错误,也许您需要调整日志记录设置。
我不太明白你的模型:
对我来说,这听起来像是从
User
到Address
的 @OneToMany,以及(如果“use”意味着“用户”)从User
到@OneToMany代码>教育信息。
这和上面有冲突。每个
User
可以有多个EducationInfo
,或者它“对一个人来说是唯一的”。OneToMany
's complement mapping on the other side of association isManyToOne
, it cannot beOneToOne
. That's what's causingEntityManager
to fail.It works when you remove the last line from
User
because then you're only left withOneToMany
toAddress
and, although not shown here, presumablyAddress
doesn't have aOneToOne
link toUser
.I'm no Scala expert; in Java you normally get an error and a stack trace printed when
EntityManager
fails to initialize; error message is not always extremely descriptive but usually says what mapping it has a problem with. Perhaps you need to tweak your logging settings if you don't get that error.I didn't quite understand your model:
That sounds like @OneToMany from
User
toAddress
to me and (if "use" meant "user") as @OneToMany fromUser
toEducationInfo
.That conflicts with above. Either you can have several
EducationInfo
perUser
or it's "unique to a person".