无法将 java.lang.String 字段设置为 java.lang.String
Posted
技术标签:
【中文标题】无法将 java.lang.String 字段设置为 java.lang.String【英文标题】:Can not set java.lang.String field to java.lang.String 【发布时间】:2016-01-23 01:56:51 【问题描述】:我目前正在开发一个带有套接字服务器的小型 MMO 应用程序。我使用的数据库是 PostgreSQL,我使用的是 Hibernate ORM。 在请求单个用户拥有的所有头像时,我偶然发现了一个例外。
我参加了 3 个课程,分别是:
游戏服务器客户端 数据库 数据库.查询当用户(客户端应用程序)通过套接字向服务器发送请求时,会调用一个方法,该方法应返回所有头像的 JsonString。
然而,使用 HQL 查询 from UserOwnsAvatar where user = :username
并将结果放入 UserOwnsAvatar 对象的 ArrayList 中,它会返回一个 Can not set java.lang.String field nl.marcusink.mmo.server.database.table.User.username to java.lang.String
完整的堆栈跟踪是:
org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.String nl.marcusink.mmo.server.database.table.User.username] by reflection for persistent property [nl.marcusink.mmo.server.database.table.User#username] : Mjollnir94
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:43)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:223)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4594)
at org.hibernate.type.EntityType.toLoggableString(EntityType.java:505)
at org.hibernate.internal.util.EntityPrinter.toString(EntityPrinter.java:87)
at org.hibernate.engine.spi.QueryParameters.traceParameters(QueryParameters.java:281)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:194)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1268)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)
at nl.marcusink.mmo.server.database.Database$Queries.avatarsRequest(Database.java:134)
at nl.marcusink.mmo.server.connection.GameServerClient.run(GameServerClient.java:91)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field nl.marcusink.mmo.server.database.table.User.username to java.lang.String
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
at java.lang.reflect.Field.get(Field.java:393)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:39)
... 11 more
查询代码为:
Query query = session.createQuery("from UserOwnsAvatar where user = :username");
query.setParameter("username", username);
ArrayList<UserOwnsAvatar> ownedAvatars = (ArrayList<UserOwnsAvatar>) query.list();
最后一行是错误的原因,有什么想法吗?
编辑
@Id
@ManyToOne(targetEntity = User.class)
@JoinColumn(name = "username", nullable = false)
private User user;
@Id
@OneToOne(targetEntity = Avatar.class)
@JoinColumn(name = "avatar", nullable = false, unique = true)
private Avatar avatar;
这里的用户名等于User对象的用户名,即:
@Id
@Column(name = "username", unique = true, nullable = false)
private String username;
【问题讨论】:
能否请您出示与username
相关的代码...
也许您需要将public void setUsername(String username) this.username = username;
添加到User
类中。
我为每个表类生成了所有的 getter 和 setter。 public void setUsername(String username) this.username = username;
就是其中之一。这不可能是我认为的问题
别介意我纠正自己:查询:user
tablefield:username
哦,那个错误信息是一团糟。从堆栈跟踪中可以看出,它尝试get
,但会产生错误消息“无法设置”。在查看UnsafeFieldAccessorImpl .ensureObj
的源代码后,我得出结论,尽管错误消息侧重于值,但它是 instance,在其上进行了尝试,而不是 @987654335 类型@…
【参考方案1】:
您必须设置完整的(或仅具有相关字段的对象)而不是该对象的一个特定值。
我的理解是您在设置参数时尝试设置String
,但该列的类型为User
。 Hibernate 正在尝试在 String
上调用 getUsername
方法,这就是错误的原因。
所以把你的代码改成这样:
User user = getSomeUser();
Query query = session.createQuery("from UserOwnsAvatar where user.username = :username");
query.setParameter("username", user);
【讨论】:
您的想法是正确的,但您的示例代码需要修改。它解决了我遇到的类似问题。【参考方案2】:user = :username 不正确。 user 不是实体的字符串字段。使用联接或使用休眠条件为用户创建别名并添加限制,例如 .add(Restriction.eq("user.username",username)。
【讨论】:
以上是关于无法将 java.lang.String 字段设置为 java.lang.String的主要内容,如果未能解决你的问题,请参考以下文章
DBunit 生成 java.lang.ClassCastException:尝试加载 CLOB 字段时无法将 java.lang.String 强制转换为 oracle.sql.CLOB
Spring - 无法将java.lang.String类型的属性值转换为必需类型java.util.Date
无法将类型 [java.lang.String] 的属性值转换为所需类型 [java.lang.Integer]
无法将 java.lang.String 类型的对象转换为类型 - FirebaseUI