如何在JPA中使用命名查询而无需在persistence.xml中列出实体?

时间:2017-06-09 14:28:00

标签: java maven tomcat jpa openjpa

我可以使用 out 检索并保留实体,并将其列在persistence.xml中,但如果我想使用@NamedQuery,则除非我无效在persistence.xml中列出它。有没有解决的办法?

我正在使用Tomcat 8和OpenJPA 2.4.2。

的persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence
        version="2.1"
        xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

    <!-- Used for persisting events, authentication pieces -->
    <persistence-unit name="PushPersistence" transaction-type="RESOURCE_LOCAL">

        <!-- Use Apache's OpenJPA -->
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

        <!-- Our backing store is our data source from context.xml -->
        <non-jta-data-source>java:comp/env/jdbc/webservice</non-jta-data-source>

        <!--
            Without this, I can load and persist the entity but 
            CANNOT use Named Queries                        
        -->
        <class>push.authentication.AuthCredentials</class>

        <!-- Don't require listing the managed classes here -->
        <exclude-unlisted-classes>false</exclude-unlisted-classes>

        <properties>
            <property name="openjpa.DynamicEnhancementAgent" value="true"/>
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
            <property name="openjpa.Log" value="SQL=TRACE"/>
            <property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, PrettyPrintLineLength=72, PrintParameters=true, MaxActive=10, MaxIdle=5, MinIdle=2, MaxWait=60000"/>
        </properties>

    </persistence-unit>
</persistence>

的Maven:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>MyProj</artifactId>
    <version>1.0</version>

    <packaging>war</packaging>

    <!-- Tell Maven what language version to use -->
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
        <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <version>2.0</version>
        </dependency>

        <!-- Enables the annotations, etc needed -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.exterprise</groupId>
                    <artifactId>cdi-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Our jersey libs -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>2.25.1</version>
        </dependency>

        <!-- CDI to JAX-RS Binding -->
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.containers.glassfish/jersey-gf-cdi-ban-custom-hk2-binding -->
        <dependency>
            <groupId>org.glassfish.jersey.containers.glassfish</groupId>
            <artifactId>jersey-gf-cdi</artifactId>
            <version>2.14</version>
        </dependency>

        <!-- Jackson -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.25.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.jboss.weld.servlet/weld-servlet-core -->
        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet-core</artifactId>
            <version>3.0.0.Final</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.jboss.weld/weld-core-impl -->
        <dependency>
            <groupId>org.jboss.weld</groupId>
            <artifactId>weld-core-impl</artifactId>
            <version>3.0.0.Final</version>
        </dependency>

        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>2.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa-maven-plugin</artifactId>
            <version>2.4.2</version>
        </dependency>

    </dependencies>

    <build>

        <!-- We don't use the version number in the war file name -->
        <finalName>MyProj</finalName>

        <plugins>

            <!-- Enhances the JPA classes -->
            <plugin>
                <groupId>org.apache.openjpa</groupId>
                <artifactId>openjpa-maven-plugin</artifactId>
                <version>2.4.2</version>
                <executions>
                    <execution>
                        <id>JPA Enhance</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                        <configuration>
                            <includes>**/push/*.class</includes>
                            <persistenceXmlFile>${project.basedir}/src/main/resources/META-INF/persistence.xml</persistenceXmlFile>
                            <toolProperties>
                                <property>
                                    <name>addDefaultConstructor</name>
                                    <value>false</value>
                                </property>
                                <property>
                                    <name>enforcePropertyRestrictions</name>
                                    <value>true</value>
                                </property>
                            </toolProperties>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

命名查询的类声明:

package push;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Base64;
import java.util.Date;

@Entity
@NamedQueries(
    {
        @NamedQuery(
            name = "Users.findByName",
            query = "SELECT ac FROM Users ac WHERE ac.userName = :userName"
        )
    }
)
@Table(name = "PushClient")
public class Users
{
    ...
}

1 个答案:

答案 0 :(得分:0)

我读了EntityManager接口,如果没有使用给定名称定义查询,或者发现查询字符串无效或者发现查询结果无法分配给指定类型,则会抛出IllegalArgumentException如果基于你的代码片段得到IllegalArgumentException,我认为第三个是你的情况,尝试使用

EntityManager.createNamedQuery(java.lang.String name);

而不是

EntityManager.createNamedQuery(java.lang.String name,
                               java.lang.Class<T> resultClass);

看看你是否得到相同的结果