Ошибка при компиляции запроса: тип абстрактной схемы "сущность" неизвестен
Я разрабатываю игру с подключением к базе данных и использую 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
Ответы
Ответ 1
У тебя должно быть
SELECT g FROM Game g//you have game
но у вас есть game
вместо Game
.
Аннотация @Table
используется для БД.
Если вам нужно изменить имя в вашем JPQL
, используйте аннотацию @Entity
: @Entity(name="nameUsedInJPQL") => nameUsedInJPQL is used in your JPQL.
Если вы ничего не указали в своем @Entity
, то используется имя класса Entity с учетом регистра.
Ответ 2
В моем случае я забыл зарегистрировать его в файле persistence.xml.
Ответ 3
У меня была такая же ситуация, но мой JPQL-запрос был прав! Это произошло в Glassfish 4.1 (сборка 13) (с EclipseLink).
После нескольких разборок и некоторого комментирования кода я выяснил, что основная причина "Тип абстрактной схемы" MyEntity "неизвестна" была Некоторое использование кода лямбды Java 8 внутри класса сущности.
Кажется, что любая функция Java 8 не поддерживается (пока) в версии EclipseLink, которая поставляется с GF. Подробнее см. отчет об ошибке.
Надеюсь, что это поможет.
Ответ 4
Имя, которое будет использоваться для запросов JPQL, определяется как простое имя класса сущности - Game
или Human
в вашем случае. Его можно переопределить атрибутом name
аннотации @Entity
. @Table
- это аннотация физического отображения и не влияет на имя объекта в запросе.
Он работает с Human
, потому что строка запроса не чувствительна к регистру.
Ответ 5
имя класса должно быть там не имя таблицы в вашем запросе
SELECT g FROM Game g
Ответ 6
У нас возникла проблема из-за обновления библиотеки org.eclipse.persistence.eclipselink с 2.4.0 до 2.5.1. После обновления до версии 2.6.2 он снова работает.