无法确定类型:java.util.List
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16117923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Could not determine type for: java.util.List
提问by Kamil Janowski
I'm rather new to Hibernate and it turns out it's not a simple technology to learn... In the project I use hibernate version 4.2.0.CR1. I'm trying to create a base class for all database entities, as they all are supposed to contain some identifier and date of creation. What is weird is that at first, I crated class User and UserPicture without any base class and it worked perfectly fine and now that I added it, even though it's supposed to work just like before, it doesn't o_O and it keeps on throwing some weird exception about my list of pictures, that was not thrown before... So I keep on getting following stacktrace:
我对 Hibernate 比较陌生,结果证明它不是一项简单的技术学习......在项目中我使用了 Hibernate 版本 4.2.0.CR1。我正在尝试为所有数据库实体创建一个基类,因为它们都应该包含一些标识符和创建日期。奇怪的是,起初,我在没有任何基类的情况下创建了 User 和 UserPicture 类,它运行得非常好,现在我添加了它,即使它应该像以前一样工作,但它没有 o_O 并且它继续抛出关于我的图片列表的一些奇怪的异常,以前没有抛出过......所以我继续关注堆栈跟踪:
org.hibernate.MappingException: Could not determine type for: java.util.List, at table: User, for columns: [org.hibernate.mapping.Column(profilePicture)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:314)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:292)
at org.hibernate.mapping.Property.isValid(Property.java:239)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:469)
at org.hibernate.mapping.UnionSubclass.validate(UnionSubclass.java:61)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1283)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1734)
at love.commons.database.DBManager.<init>(DBManager.java:28)
at love.commons.database.DBManagerTest.<clinit>(DBManagerTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
AbstractEntity:
抽象实体:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements Serializable{
private static final long serialVersionUID = 1L;
protected Long id;
protected Date creationDate = new Date();
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.TABLE)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column
@NotNull
@Temporal(TemporalType.DATE)
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
User:
用户:
@Entity
@Table(name="User")
public class User extends AbstractEntity {
private static final long serialVersionUID = 1L;
@Column (unique=true, length=30)
@NotNull
private String login;
@Column (length=32)
@NotNull
private String password;
@NotNull
@Email
@Column (unique=true, length=80)
private String email;
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="owner")
private List<UserPicture> profilePictures = new LinkedList<UserPicture>();
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Transient
public void encryptPassword() {
this.password = md5(password);
}
public List<UserPicture> getProfilePicture() {
return Collections.unmodifiableList(profilePictures);
}
public void addProfilePicture(UserPicture profilePicture) {
profilePicture.setOwner(this);
profilePictures.add(profilePicture);
}
@Transient
private String md5(String input) {
String md5 = null;
if(null == input) return null;
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(input.getBytes(), 0, input.length());
md5 = new BigInteger(1, digest.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
}
UserPicture:
用户图片:
@Entity
public class UserPicture extends AbstractEntity {
private static final long serialVersionUID = 1L;
@Column(length=734004)
private byte [] picture = null;
@ManyToOne(fetch=FetchType.LAZY)
@Column(name="owner")
@JoinColumn(nullable=false,name="id")
private User owner;
public UserPicture() {
picture = null;
}
public UserPicture(InputStream stream) {
try {
this.picture = new byte[stream.available()];
stream.read(picture);
} catch (IOException e) {
e.printStackTrace();
}
}
public UserPicture(byte [] picture) {
this.picture = picture;
}
public byte[] getPicture() {
return picture;
}
public void setPicture(byte[] picture) {
this.picture = picture;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
So what am I doing wrong? Why do I keep on getting the exception?
那我做错了什么?为什么我不断收到异常?
回答by JB Nizet
AbstractEntity must not be annotated with @Entity
and @Inheritance
. It must be annotated with @MappedSuperclass
. Indeed, this inheritance is only used to inherit common attributes, and that's what MappedSuperclass
is for.
AbstractEntity 不能用@Entity
and注释@Inheritance
。必须用@MappedSuperclass
. 确实,这个继承只是用来继承公共属性,这就是MappedSuperclass
目的。
The exception you get is caused by the lack of coherence in the position of your mapping annotations. The base superclass annotated the getters, and the subclasses annotate the fields. Hibernate uses the position of the Id annotation to determine the access type of the entity. Since @Id is on a getter, it only considers the annotations placed on getters, and ignores those placed on fields. Put all your annotations either on fields (which I would recommend) or on getters.
您得到的异常是由于映射注释的位置缺乏一致性造成的。基超类注释 getter,子类注释字段。Hibernate 使用 Id 注释的位置来确定实体的访问类型。由于@Id 在一个 getter 上,它只考虑放在 getter 上的注解,而忽略放在字段上的注解。将所有注释放在字段(我推荐)或 getter 上。
Moreover, your getter is badly named. It should be getProfilePictures()
and not getProfilePicture()
.
此外,你的吸气剂名字很糟糕。应该是getProfilePictures()
,不是getProfilePicture()
。
回答by O.Badr
From Hibernate 5.2 documentation:
By default, the placement of the @Id annotation gives the default access strategy.
默认情况下,@Id 注释的位置给出了默认访问策略。
For your case, hibernate will use AccessType.PROPERTY
both for UserPicture
and User
entities hence the exception, to use field mapping strategy, you should define @Accessstrategy explicitly :
对于您的情况,hibernate 将同时使用AccessType.PROPERTY
forUserPicture
和User
实体,因此例外,要使用字段映射策略,您应该明确定义@Access策略:
@Entity
@Table(name="User")
@Access( AccessType.FIELD )
public class User extends AbstractEntity {
...
}
@Entity
@Access( AccessType.FIELD )
public class UserPicture extends AbstractEntity {
....
}
回答by Amine Aouffen
I had the same problem, i figured out that hibernate tried to use Parent using properties accessorso i solved the problem by using @Access annotation to force use fields
我遇到了同样的问题,我发现 hibernate 尝试使用属性访问器来使用 Parent 所以我通过使用 @Access 注释强制使用字段解决了这个问题
@Entity
@Table(name = "MyTable")
@Access(AccessType.FIELD)
public class MyEntity{
......
}
回答by AhuraMazda
you can try to add @ElementCollection mapping above the List declaration.
您可以尝试在 List 声明上方添加 @ElementCollection 映射。