无法确定类型:java.util.List

Posted

技术标签:

【中文标题】无法确定类型:java.util.List【英文标题】:Could not determine type for: java.util.List 【发布时间】:2013-04-20 07:34:15 【问题描述】:

我对 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$1.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)

抽象实体:

@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;


用户:

@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;
   

用户图片:

@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;
   

那我做错了什么?为什么我不断收到异常?

【问题讨论】:

这可能会有所帮助:***.com/questions/3774198/… “为什么我不断收到异常?”导致您一次又一次地继续运行错误的代码。 【参考方案1】:

AbstractEntity 不得使用@Entity@Inheritance 进行注释。它必须使用@MappedSuperclass 进行注释。确实,这种继承只用于继承公共属性,这就是MappedSuperclass 的用途。

您得到的异常是由于映射注释的位置缺乏连贯性引起的。基础超类注释了 getter,子类注释了字段。 Hibernate 使用 Id 注解的位置来确定实体的访问类型。由于@Id 在 getter 上,它只考虑放在 getter 上的注解,而忽略那些放在字段上的注解。将所有注释放在字段(我会推荐)或 getter 上。

此外,您的吸气剂命名不当。它应该是getProfilePictures() 而不是getProfilePicture()

【讨论】:

现在我得到:实体映射中的重复列:UserPicture 列:id(应该使用 insert="false" update="false" 映射) 你做了哪些改变?您是否已将所有映射注释移至字段? 你提到的所有内容 + 我从 UserPicture.owner 中删除了@Column 我通过简单地从 @JoinColumn 中删除 ",name="id"" 来修复它。谢谢! :D【参考方案2】:

来自Hibernate 5.2 documentation:

默认情况下,@Id 注解的位置给出默认值 访问策略。

对于您的情况,hibernate 将对UserPictureUser 实体使用AccessType.PROPERTY,因此例外,要使用字段映射策略,您应该明确定义@Access 策略:

@Entity
@Table(name="User")
@Access( AccessType.FIELD )
public class User extends AbstractEntity 
    ...


@Entity
@Access( AccessType.FIELD )
public class UserPicture extends AbstractEntity 
    ....

【讨论】:

【参考方案3】:

我遇到了同样的问题,我发现 hibernate 尝试使用属性访问器使用 Parent 所以我通过使用 @Access 注释来强制使用字段解决了这个问题

@Entity
@Table(name = "MyTable")
@Access(AccessType.FIELD)
public class MyEntity
     ......

【讨论】:

【参考方案4】:

您可以尝试在 List 声明上方添加 @ElementCollection 映射。

【讨论】:

感谢您的回答。那是 6 年前的事了:D 同时我设法正确地学习了休眠:P @ElementCollection 仅适用于简单类型。在这种情况下您不能使用它。我不记得 6 年前我是如何解决我的问题的,但最终我确实让它工作了 我知道那是旧时代了。我只认为如果其他人像我一样搜索答案,这对他有用,因为它对我有用。 如果你有一个整数或字符串列表,它确实有效。如果这些是更复杂的类,则不会

以上是关于无法确定类型:java.util.List的主要内容,如果未能解决你的问题,请参考以下文章

无法处理托管/反向引用“defaultReference”:反向引用类型 (java.util.List) 与托管类型不兼容

无法将类型“java.lang.String”的属性值转换为属性“事务”所需的类型“java.util.List”

dom4j 不兼容的类型: java.util.List (org.dom4j.Node)无法转换为java.util.List(org.dom4j.Element)

无法解析方法'create(okhttp3.MediaType, java.util.List<java.lang.String>)'

类型特定的 java.util.List.toArray() [重复]

获取 java.util.List 的泛型类型