我正在开发一个带有数据库连接的游戏,我使用JPA来保存我的数据。这是我的游戏实体:
@Entity
@Table(name = "game")
public class Game implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "game_id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "nbTurns")
private int nbTurns;
@Column(name = "playedOn")
@Temporal(TemporalType.TIMESTAMP)
private Date playedOn;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "game_humans", joinColumns = @JoinColumn(name = "game_id"))
@MapKeyColumn(name = "human_id")
@Column(name = "isDead")
private Map<Human, Boolean> humans;
这是我的人类实体:
@Entity
@Table(name = "human")
public class Human implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "name")
private String name;
@OneToOne
private Building building;
为了获取数据库中存储的所有人员的列表,我使用了这个 DAO,它工作得很好并且还获取了 Building 实体:
public class HumanDAO implements DAO<Human> {
// ...
public List<Human> getAllHumans() {
TypedQuery<Human> query = em.createQuery("SELECT h FROM human h ORDER BY h.name", Human.class);
return query.getResultList();
}
问题是,当我尝试执行相同操作以使用 JPQL 查询获取所有游戏的列表时
SELECT g FROM game g
,我收到此错误:
[EL Info]: 2013-11-25 13:40:27.761--ServerSession(1943119327)--EclipseLink, version: Eclipse Persistence Services - 2.5.0.v20130507-3faac2b
[EL Info]: connection: 2013-11-25 13:40:28.151--ServerSession(1943119327)--file:/Users/amine/Documents/workspace/ZombiesServer/target/classes/_ZombiesServer login successful
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Problem compiling [SELECT g FROM game g].
[14, 18] The abstract schema type 'game' is unknown.
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1585)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1605)
at com.amine.zombies.DAO.GameDAO.getAllGames(GameDAO.java:80)
at com.amine.zombies.application.Application.main(Application.java:21)
... 6 more
你应该有
SELECT g FROM Game g//you have game
但是你有
game
而不是 Game
。
@Table
注释用于DB。
如果您需要更改
JPQL
中的名称,请使用 @Entity
注释:@Entity(name="nameUsedInJPQL") => nameUsedInJPQL is used in your JPQL.
如果您未在
@Entity
中指定任何内容,则使用区分大小写的实体类名称。
就我而言,我忘记在 persistence.xml 中注册它。
我刚刚遇到了同样的情况,但我的 JPQL 查询是正确的!它出现在 Glassfish 4.1(版本 13)(使用 EclipseLink)中。
经过几次谷歌搜索和一些代码注释后,我发现“抽象模式类型'MyEntity'未知”的根本原因是在实体类中使用了Java 8 lambda代码。
GF 附带的 EclipseLink 版本似乎尚不支持 Java 8 的任何功能。更多信息,请参阅 有关该问题的错误报告。
希望这有帮助。
查询中应该有类名而不是表名 从游戏 g 中选择 g
用于 JPQL 查询的名称定义为实体类的简单名称 - 在您的情况下为
Game
或 Human
。它可以被 name
注释的 @Entity
属性覆盖。 @Table
是物理映射注释,不影响查询中的实体名称。
它确实可以与
human
一起使用,因为查询字符串不区分大小写。
我们遇到这个问题是由于 org.eclipse.persistence.eclipselink 库从 2.4.0 更新到 2.5.1。更新到2.6.2后就可以再次使用了。
如果您在捆绑包中调用 persistence.xml,则必须在您的捆绑包(或多个捆绑包)之前启动 org.eclipse.persistence.jpa。如果没有,您将得到相同的异常。您还将看到数据库中尚未创建这些表。因此,最好始终将 org.eclipse.persistence 添加为清单中的导入包。
就我而言,没有答案可以帮助我。我的 JPA 项目使用 Java 14 和 EclipseLink 3.0.0 作为提供程序,并且 EclipseLink 似乎不支持新的 Java 版本。切换回 Java 1.7 就成功了。
就我而言,从 JDK 21 降级到 JDK 11 是有效的。 感谢上帝。