为什么编译器无法识别元模型属性?

时间:2010-08-11 13:26:40

标签: java eclipselink jpa-2.0 criteria-api

java se 6项目是否支持eclipselink jpa2的标准api?如果没有,那就是我的问题。 我是否需要在persistence.xml中为条件api指定任何特殊内容?

这是我的标准查询:

 final EntityType<Meaning> Meaning_ = em.getMetamodel().entity(Meaning.class);
    final CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Integer> cq = cb.createQuery(Integer.class);
    final Root<Meaning> meng = cq.from(Meaning.class);
    cq.where(meng.get(Meaning_.lastPublishedDate)); //this attributes are not recognized/found
    cq.select(meng.get(Meaning_.objId));            // "                "                   
    TypedQuery<Integer> q = em.createQuery(cq); 
    return q.getResultList();

这是我的意义实体:

@Entity
public class Meaning implements Serializable{
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int objId;

public int getObjId() {
    return objId;
}

@Temporal(javax.persistence.TemporalType.DATE)
private Date lastPublishedDate = null;//never

public Date getLastPublishedDate(){
        return lastPublishedDate;
    }
}

4 个答案:

答案 0 :(得分:3)

关于您的代码

我没有检查条件查询本身的正确性,但正如Chris所提到的,您正在将静态元模型类与EntityType混合,而不会暴露您正在寻找的内容。假设您已生成元模型类,请删除第一行并导入生成的Meaning_

// final EntityType<Meaning> Meaning_ = em.getMetamodel().entity(Meaning.class); 
final CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Integer> cq = cb.createQuery(Integer.class);
final Root<Meaning> meng = cq.from(Meaning.class);
cq.where(meng.get(Meaning_.lastPublishedDate)); // add the appropriate import 
cq.select(meng.get(Meaning_.objId));            
TypedQuery<Integer> q = em.createQuery(cq); 
return q.getResultList();

关于静态(规范)元模型类的生成

以下是我用于使用EclipseLink生成规范元模型类的Maven设置:

<project>
  ...
  <repositories>
    <!-- Repository for EclipseLink artifacts -->
    <repository>
      <id>EclipseLink Repo</id>
      <url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo/</url>
    </repository>    
    ...
  </repositories>
  ...
  <pluginRepositories>
    <!-- For the annotation processor plugin -->
    <pluginRepository>
      <id>maven-annotation-plugin</id>
      <url>http://maven-annotation-plugin.googlecode.com/svn/trunk/mavenrepo</url>
    </pluginRepository>
  </pluginRepositories>
  ...
  <dependencies>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>eclipselink</artifactId>
      <version>2.1.0</version>
    </dependency>
    <!-- optional - only needed if you are using JPA outside of a Java EE container-->
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>javax.persistence</artifactId>
      <version>2.0.2</version>
    </dependency>
  <dependencies>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <version>1.3.1</version>
        <executions>
          <execution>
            <id>process</id>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <!-- Without this, the annotation processor complains about persistence.xml not being present and fail -->
              <compilerArguments>-Aeclipselink.persistencexml=src/main/resources/META-INF/persistence.xml</compilerArguments>
              <!-- For an unknown reason, the annotation processor is not discovered, have to list it explicitly -->
              <processors>
                <processor>org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor</processor>
              </processors>
              <!-- source output directory -->
              <outputDirectory>${project.build.directory}/generated-sources/meta-model</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <inherited>true</inherited>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          <compilerArgument>-proc:none</compilerArgument>
        </configuration>
      </plugin>
      ...
    </plugins>
  </build>
</project>

一些意见:

  • EclipseLink注释处理器由主工件提供,没有额外的依赖关系来添加。
  • 由于未知原因,未发现注释处理器,我必须将其明确列为<processor>
  • 如果没有-Aeclipselink.persistencexml,注释处理器会抱怨persistence.xml没有出现并失败。
  • 我更喜欢在target下生成源代码(我想要clean来清理它)。

使用此配置,可以适当地生成和编译静态元模型类。

答案 1 :(得分:2)

看起来您正在将静态元模型类与EntityType类混合使用。 EntityType上没有任何元模型的属性 - 您必须使用getSingularAttributegetCollection方法访问它们,例如:

meng.get(Meaning_.getSingularAttribute("someString", String.class))

或者您可以直接使用静态元模型,但您必须手动创建_类或使用http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29

中所述的生成器

答案 2 :(得分:1)

您使用的是什么IDE?

JPA 2.0中的Criteria API支持基于字符串的属性引用,以及必须通过某个工具编译的类型检查常量。

你可以使用字符串API而不做任何特殊的事情, 即。

cq.where(meng.get("lastPublishedDate"));
cq.select(meng.get("objId"));

要使用类型检查的常量,您需要以某种方式生成这些静态类。如果您使用的是Eclipse IDE,那么Eclipse JPA 2.0支持(Dali)可以为您自动生成这些类。

EclipseLink还提供了一个可以与ant,javac一起使用或与IDE集成的生成器。

请参阅, http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_%28ELUG%29

答案 3 :(得分:0)

如果您在Eclipse IDE中尝试此操作,并在您的pom.xml中执行:

<outputDirectory> src/main/generated-java </outputDirectory>

对于metalmodel类,解决此问题的一种方法是选择New / Source Folder 并在这里放置相同的rute src / main / generated-java,自动创建文件夹与生成的类。

尝试识别这些课程,对我来说没问题!