在使用Spring + Hibernate JPA

时间:2016-11-11 00:25:44

标签: java spring hibernate spring-mvc jpa

  

请考虑关闭此问题。在使用JPA 2.0时,似乎我的用例没有解决方案。在这种情况下,我忽略了JPA 2.0的局限性。如果不使用persistence.xml,JPA 2.0不支持自定义实体。

我正在尝试测试我的应用程序以使用Spring + Hibernate JPA,同时避免使用专用的persistence.xml。完全使用注释。

我正在使用的API是IBM WebSphere 8.0上的Spring 4.3.3和Hibernate JPA-2.0

我不知道我的用例可能存在差距。我也可能是一个简单的错过。

目标是执行本机查询并将结果映射到bean类。 我能够用实体测试我的应用程序。 JPA能够根据实际数据库表验证它们的映射。

为什么要使用原生查询而不是写完整实体 - >查询涉及多个连接。不需要将查询中涉及的所有表都包括为实体。

与jpa相关的应用程序上下文xml的一部分如下所示                   

<bean id="jpaVendorApdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="databasePlatform" value="org.hibernate.dialect.DB2Dialect"></property>
    <property name="showSql" value="true" />
</bean>

<bean id="testEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="testDB2DataSource" />
  <property name="packagesToScan" value="com.app.dao" />
  <property name="jpaVendorAdapter">
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
  </property>
  <property name="jpaProperties">
     <props>
        <prop key="hibernate.hbm2ddl.auto">validate</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.DB2Dialect</prop>
     </props>
  </property>

为我的案例添加一个简单的例子 本机查询的bean类如下所示

public class OwnerDetails implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Id
    private String userInitials;

    private String teamCd;

    public String getUserInitials() {
        return userInitials;
    }

    public void setUserInitials(String userInitials) {
        this.userInitials= userInitials;
    }

    public String getTeamCd() {
        return teamCd;
    }

    public void setTeamCd(String teamCd) {
        this.teamCd= teamCd;
    }
}

查询为

  

选择B.USER_INITS作为userInitials,B.TEAM_CD作为teamCd FROM APPTEAM   一个JOIN PQID B ON A.APP_OWNER_ID = B.SIGN_ON_ID WHERE A.APP_NAME =   :APPNAME

执行本机查询的代码块

Query query = entityManager.createNativeQuery(queryString, className)(QUERY_STRING, OwnerDetails.class);
    query.setParameter("appName", "TESTAPP");


    OwnerDetails  result = (OwnerDetails ) query.getSingleResult();

我在尝试执行查询时遇到异常

  

引起:org.hibernate.MappingException:未知实体:   com.app.dao.entity.OwnerDetails

我知道这是因为不包括@Entity注释 但是当我包含实体注释时,我得到了一个不同的错误

  

引起:org.hibernate.HibernateException:缺少表:OwnerDetails

     

...

     

引起:javax.persistence.PersistenceException:[PersistenceUnit:default]无法构建EntityManagerFactory

我想知道在不使用persistence.xml时设置JPA的缺失链接

  

更新 - 因为API是JPA 2.0,不支持命名本机查询

2 个答案:

答案 0 :(得分:1)

尝试以下步骤。

  1. 在您的班级中添加@Entity注释
  2. 在您的班级中添加@Table注释

     @Entity
     @Table(name="YourTableName") //if you do not put name, the dafault value is your class name
     public class OwnerDetails implements Serializable {
     }
    
  3. 确保您的桌子存在与否。
  4. 修改

    如果OwnerDetails不是实体并且您使用的是JPA 2.1,那么您可以使用SqlResultSetMapping with ConstructorResult

答案 1 :(得分:0)

如果您使用的是JPA 2.1版本,请确保您有这些内容:

@NamedNativeQuery (name = "some name"
query = "SELECT B.USER_INITS as userInitials, B.TEAM_CD as teamCd FROM APPTEAM A JOIN PQID B ON A.APP_OWNER_ID = B.SIGN_ON_ID WHERE A.APP_NAME = :appName"
resulSetMapping = "OwnerDetails") 

@SqlResultSetMapping(name="some name", classes = {
    @ConstructorResult(targetClass = OwnerDetail.class, 
    columns = {@ColumnResult(name="userInitials"), @ColumnResult(name="teamCd")})
}) 

稍后您只需投射结果。 但是,如果您使用的JPA版本低于2.1,那是不可能的。