JPA/Hibernate 映射:“QuerySyntaxException:播放器未映射……”

Posted

技术标签:

【中文标题】JPA/Hibernate 映射:“QuerySyntaxException:播放器未映射……”【英文标题】:JPA/Hibernate mapping: “QuerySyntaxException: Player is not mapped…” 【发布时间】:2014-09-18 06:14:23 【问题描述】:

我在设置一个新的 Hibernate 项目时遇到了一个非常基本的问题。

我有一个实体如下:

@Entity(name = "Player")
public class PlayerEntity implements Serializable  

    private static final long serialVersionUID = 6584040856373261900L;

    @Id
    private long id;

    @Column
    private String forename;

    @Column
    private String surname;

    @Column
    private String team;

    @Column
    @Enumerated(EnumType.STRING)
    private Position position;

    @Column
    private boolean selected;

    @Column
    private int totalPoints;

    public PlayerEntity() 
    

    public PlayerEntity(final long id, final String forename, final String surname, final String team,
            final Position position, final boolean selected, final int totalPoints) 
        this.id = id;
        this.forename = forename;
        this.surname = surname;
        this.team = team;
        this.position = position;
        this.selected = selected;
        this.totalPoints = totalPoints;
    

    /**
     * @return the id
     */
    public long getId() 
        return id;
    

    /**
     * @param id the id to set
     */
    public void setId(long id) 
        this.id = id;
    

    /**
     * @return the forename
     */
    public String getForename() 
        return forename;
    

    /**
     * @param forename the forename to set
     */
    public void setForename(String forename) 
        this.forename = forename;
    

    /**
     * @return the surname
     */
    public String getSurname() 
        return surname;
    

    /**
     * @param surname the surname to set
     */
    public void setSurname(String surname) 
        this.surname = surname;
    

    /**
     * @return the team
     */
    public String getTeam() 
        return team;
    

    /**
     * @param team the team to set
     */
    public void setTeam(String team) 
        this.team = team;
    

    /**
     * @return the position
     */
    public Position getPosition() 
        return position;
    

    /**
     * @param position the position to set
     */
    public void setPosition(Position position) 
        this.position = position;
    

    /**
     * @return the selected
     */
    public boolean isSelected() 
        return selected;
    

    /**
     * @param selected the selected to set
     */
    public void setSelected(boolean selected) 
        this.selected = selected;
    

    /**
     * @return the totalPoints
     */
    public int getTotalPoints() 
        return totalPoints;
    

    /**
     * @param totalPoints the totalPoints to set
     */
    public void setTotalPoints(int totalPoints) 
        this.totalPoints = totalPoints;
    

以及如下访问数据的数据服务:

public class PlayerDataServiceJpa implements PlayerDataService 

    @PersistenceContext
    private EntityManager entityManager;

    public void addPlayers(final List<Player> players) 
        for (final Player domainPlayer : players) 
            final PlayerEntity entityPlayer = new PlayerEntity();

            BeanUtils.copyProperties(domainPlayer, entityPlayer);

            entityManager.persist(entityPlayer);
        
    

    public List<Player> getPlayers() 
        final List<Player> domainPlayers = new ArrayList<Player>();

        final List<PlayerEntity> entityPlayers = entityManager.createQuery("SELECT tc FROM PlayerEntity tc", PlayerEntity.class).getResultList();

        for (final PlayerEntity entityPlayer : entityPlayers) 
            final Player domainPlayer = new Player();

            BeanUtils.copyProperties(entityPlayer, domainPlayer);

            domainPlayers.add(domainPlayer);
        

        return domainPlayers;
    

然后我尝试按如下方式对数据服务进行单元测试:

@Transactional      
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "/hsqlDatasourceContext.xml", "/testApplicationContext.xml")
public class PlayerDataServiceJpaTest 

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    @Qualifier(value = "playerDataServiceJpa")
    private PlayerDataServiceJpa playerDataServiceJpa;

    @Test
    public void testGetPlayers() 
        // arrange
        final PlayerEntity player = TestDataUtil.createEntityPlayer(1);
        entityManager.persist(player);

        PlayerEntity find = entityManager.find(PlayerEntity.class, TestDataUtil.PLAYER_1_ID);
        assertThat(find).isNotNull();
        assertThat(find.getForename()).isEqualTo(TestDataUtil.PLAYER_1_FORENAME);

        // act
        final List<Player> players = playerDataServiceJpa.getPlayers();

        // assert
        assertThat(players).hasSize(1);

        final Player retrievedPlayer = players.get(0);
        assertThat(retrievedPlayer.getId()).isEqualTo(TestDataUtil.PLAYER_1_ID);
        assertThat(retrievedPlayer.getForename()).isEqualTo(TestDataUtil.PLAYER_1_FORENAME);
        assertThat(retrievedPlayer.getSurname()).isEqualTo(TestDataUtil.PLAYER_1_SURNAME);
        assertThat(retrievedPlayer.getTeam()).isEqualTo(TestDataUtil.TEST_TEAM);
        assertThat(retrievedPlayer.getTotalPoints()).isEqualTo(TestDataUtil.PLAYER_1_POINTS);
    

    @Test
    public void testAddPlayers() 
        // arrange
        final Player player1 = TestDataUtil.createModelPlayer(1);
        final Player player2 = TestDataUtil.createModelPlayer(2);

        // act
        playerDataServiceJpa.addPlayers(Arrays.asList(player1, player2));

        // assert
        final List<Player> players = playerDataServiceJpa.getPlayers();

        assertThat(players).hasSize(2);

        final Player retrievedPlayer = players.get(0);
        assertThat(retrievedPlayer.getId()).isEqualTo(TestDataUtil.PLAYER_1_ID);
        assertThat(retrievedPlayer.getForename()).isEqualTo(TestDataUtil.PLAYER_1_FORENAME);
        assertThat(retrievedPlayer.getSurname()).isEqualTo(TestDataUtil.PLAYER_1_SURNAME);
        assertThat(retrievedPlayer.getTeam()).isEqualTo(TestDataUtil.TEST_TEAM);
        assertThat(retrievedPlayer.getTotalPoints()).isEqualTo(TestDataUtil.PLAYER_1_POINTS);
    

但是,当我运行单元测试时,代码的持久化部分似乎可以工作,但是当查询运行时,我得到以下信息:

org.hibernate.hql.internal.ast.QuerySyntaxException: PlayerEntity is not mapped
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:189)
    at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:109)

我的 persistence.xml 文件位于 src/test/resources/META-INF 中

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="jpaData" transaction-type="RESOURCE_LOCAL">

        <provider>org.hibernate.ejb.HibernatePersistence</provider> 
        <class>aaa.bbb.ccc.entity.PlayerEntity</class>

    </persistence-unit>
</persistence>

hsqlDatasourceContext.xml 文件看起来像

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd   http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd    http://www.springframework.org/schema/jee  http://www.springframework.org/schema/jee/spring-jee-3.0.xsd    http://www.springframework.org/schema/tx   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc">

    <!-- HSQLDB datasource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
        <property name="url" value="jdbc:hsqldb:mem:ex;sql.syntax_mys=true" />
        <property name="username" value="sa" />
        <property name="password" value="" />
    </bean>

    <bean id="jpaProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="properties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="jpaData" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaProperties" ref="jpaProperties" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <bean id="persistenceProvider" class="org.hibernate.ejb.HibernatePersistence" />
</beans>

这个问题似乎与下面的问题JPA mapping: "QuerySyntaxException: foobar is not mapped..." 非常相似,但在我的 SELECT 语句中大小写是正确的。

有趣的是,如果我执行entityManager.find(PlayerEntity.class, 1l);,那么会找到保存的实体。

有人对问题所在有任何想法吗?我在这方面花了很长时间,但找不到解决方案。

【问题讨论】:

您能提供给我们您的 ***.hbm.xml 文件吗? 尝试将@Entity(name = "Player")更改为@Entity @Fev - 我没有 .hbm.xml 文件,因为我正在使用注释。 @Thomas - 我不希望这样做,因为我不希望使用名称“PlayerEntity”创建表。 【参考方案1】:

Doh - 代表我的小学生错误....

@Entity(name = "Player")

应该是……

@Entity
@Table(name = "Player")

【讨论】:

以上是关于JPA/Hibernate 映射:“QuerySyntaxException:播放器未映射……”的主要内容,如果未能解决你的问题,请参考以下文章

JPA(Hibernate)上的多个双向映射问题

在 JPA/Hibernate 中持久化映射到 MySQL 视图的实体

如何在pojo中用jpa或hibernate映射json字段?

如何使用 JPA/Hibernate 注释将 MySQL char(n) 列映射到实例变量?

如何使用 JPA 和 Hibernate 将 MySQL JSON 列映射到 Java 实体属性

JPA/Hibernate 将简单字符串或任意对象映射到 mysql 日期类型?