【问题标题】:How to connect OpenJPA, Spring and PostgreSQL?如何连接 OpenJPA、Spring 和 PostgreSQL?
【发布时间】:2014-09-26 15:35:23
【问题描述】:

我正在尝试将我的 PostgreSQL 数据库与 OpenJPASpring 连接。

这是我的 Spring 上下文文件。它包含 MVC 部分和 TX。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ctx="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <ctx:annotation-config/>
    <ctx:component-scan base-package="de.alex.web.pag"/>
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

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

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="pagPU"/>
        <property name="persistenceXmlLocation" value="/META-INF/persistence.xml"/>
        <property name="jpaVendorAdapter" ref="openJpaVendorAdapter"/>
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver"/>
        <property name="url" value="jdbc:postgresql://localhost:5432/box"/>
        <property name="username" value="postgres"/>
        <property name="password" value="bob"/>
    </bean>

    <bean id="openJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
        <property name="showSql" value="true"/>
        <property name="generateDdl" value="true"/>
        <property name="database" value="POSTGRESQL"/>
        <property name="databasePlatform" value="org.apache.openjpa.jdbc.sql.PostgresDictionary"/>
    </bean>
</beans>

这是我在/properties/META-INF/ 文件夹中的 persistence.xml:

<persistence 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_2_0.xsd"
             version="2.0">

    <persistence-unit name="pagPU" transaction-type="RESOURCE_LOCAL">

        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

        <class>de.alex.web.pag.entity.Category</class>
        <class>de.alex.web.pag.entity.Order</class>
        <class>de.alex.web.pag.entity.Product</class>

        <properties>
            <property name="openjpa.ConnectionURL" value="jdbc:postgresql://localhost:5432/box"/>
            <property name="openjpa.jdbc.DBDictionary" value="postgres"/>
            <property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver"/>
            <property name="openjpa.ConnectionUserName" value="postgres"/>
            <property name="openjpa.ConnectionPassword" value="bob"/>
            <property name="openjpa.Log" value="SQL=TRACE"/>
        </properties>
    </persistence-unit>
</persistence>

当我尝试在我的 IDE 中运行这个简单的脚本时,我收到了这个异常:

[2014-09-26 17:16:43] java.lang.RuntimeException: <openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: An error occurred while parsing the query filter "select c from Category c where c.id = 1". Error message: The name "Category" is not a recognized entity or identifier. Known entity names: []
    at org.apache.openjpa.kernel.exps.AbstractExpressionBuilder.parseException(AbstractExpressionBuilder.java:119)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getClassMetaData(JPQLExpressionBuilder.java:197)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.resolveClassMetaData(JPQLExpressionBuilder.java:167)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaData(JPQLExpressionBuilder.java:242)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateMetaData(JPQLExpressionBuilder.java:212)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.getCandidateType(JPQLExpressionBuilder.java:205)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder.access$200(JPQLExpressionBuilder.java:80)
    at org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder$ParsedJPQL.populate(JPQLExpressionBuilder.java:2428)
    at org.apache.openjpa.kernel.jpql.JPQLParser.populate(JPQLParser.java:61)
    at org.apache.openjpa.kernel.ExpressionStoreQuery.populateFromCompilation(ExpressionStoreQuery.java:162)
    at org.apache.openjpa.kernel.QueryImpl.newCompilation(QueryImpl.java:673)
    at org.apache.openjpa.kernel.QueryImpl.compilationFromCache(QueryImpl.java:654)
    at org.apache.openjpa.kernel.QueryImpl.compileForCompilation(QueryImpl.java:620)
    at org.apache.openjpa.kernel.QueryImpl.compileForExecutor(QueryImpl.java:682)
    at org.apache.openjpa.kernel.QueryImpl.compile(QueryImpl.java:589)
    at org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:997)
    at org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:979)
    at org.apache.openjpa.persistence.EntityManagerImpl.createQuery(EntityManagerImpl.java:102)
    in RemoteEntityManagerImpl.createQuery(RemoteEntityManagerImpl.java:39)
    in RemoteUtil.executeWithClassLoader(RemoteUtil.java:167)
    in RemoteUtil$2$1.invoke(RemoteUtil.java:102)
    at com.sun.proxy.$Proxy151.createQuery(Unknown Source)
    in JpaEngine.createQuery(JpaEngine.java:104)

我在配置 Spring 上下文或 JPA 上下文时似乎遗漏了一些重要的事情。

更新

我的实体类:

@Entity
@Table(name = "category")
public class Category {
    @Id
    @SequenceGenerator(name = "pk_seq", sequenceName = "category_table_id_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pk_seq")
    private Integer id;

    @Column(name = "name")
    private String name;

    public Category() {
    }
    // getters and setters ommited
}

UPD2

现在我得到了这个异常:

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is <openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "
de.alex.web.pag.entity.Category
de.alex.web.pag.entity.Product
de.alex.web.pag.entity.Order".

【问题讨论】:

  • 你有模型类的@Entity注解吗?
  • 是的。我更新了问题。
  • 您说您的 persistence.xml 文件位于 /properties/META-INF/ 中,而在 Spring 配置中您声明它位于 /META-INF/persistence.xml。你确定它是否正确?
  • 是的,没错。
  • 我应该将 /META-INF 文件夹移动到 /webapp/WEB-INF/ 吗?

标签: java spring jpa spring-data-jpa openjpa


【解决方案1】:

您的问题是默认情况下 OpenJPA 使用持久实体的字节码(编译时)增强,而不是说,例如,Hibernate 的运行时代理方法。

因此,您需要:

在编译时增强持久类。请参阅:http://openjpa.apache.org/entity-enhancement.html。如果您使用的是 Maven,请在您的 POM 中配置插件。如果您还使用 Eclipse,请配置该插件以节省在每次更改持久类时都必须运行完整的“mvn 全新安装”。

http://openjpa.apache.org/openjpaeclipseenhancementbuilder.html

启用运行时增强:http://openjpa.apache.org/runtime-enhancement.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-26
    • 2012-11-11
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 2012-07-08
    相关资源
    最近更新 更多