2016-03-28 2 views
0

Запросы в виде класса сущностей A в видеПочему я не могу запросить объект с предложением TYPE-WHERE, соответствующим типу объекта в JPA 2.1?

SELECT a from A a WHERE TYPE(a) = A 

завершаться

could not resolve property: class of: de.richtercloud.type.operator.nonsense.A [SELECT a from de.richtercloud.type.operator.nonsense.A a WHERE TYPE(a) = A] 

, которую я не понимаю, потому что ограничение A в A должны исключить все суперкласса экземпляры, которые Арен» t A s, а также экземпляры подкласса.

Пример:

package de.richtercloud.type.operator.nonsense; 

import java.io.File; 
import java.sql.SQLException; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 
import javax.persistence.Query; 

/** 
* Illustrates the problem/misunderstanding that storing an {@link A} and 
* querying it with a {@code WHERE TYPE([identifier]) = A} fails with 
* {@code org.hibernate.QueryException: could not resolve property: 
* class of: de.richtercloud.type.operator.nonsense.A}. 
* @author richter 
*/ 
public class NewMain { 
    private final static File DATABASE_DIR = new File("/tmp/type-operator-nonsense"); 
    private final static String DERBY_CONNECTION_URL = String.format("jdbc:derby:%s", DATABASE_DIR.getAbsolutePath()); 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws SQLException { 
     //setup database 
     EntityManagerFactory entityManagerFactory = null; 
     try { 
      Map<Object, Object> entityManagerFactoryMap = new HashMap<>(); 
      entityManagerFactoryMap.put("javax.persistence.jdbc.url", 
        String.format("%s;create=%s", DERBY_CONNECTION_URL, !DATABASE_DIR.exists())); 
      entityManagerFactory = Persistence.createEntityManagerFactory("type-operator-nonsense", 
        entityManagerFactoryMap); 

      //show issue 
      EntityManager entityManager = entityManagerFactory.createEntityManager(); 
      A a = new A(1L, "b"); 
      entityManager.getTransaction().begin(); 
      entityManager.persist(a); 
      entityManager.flush(); 
      Query query = entityManager.createQuery("SELECT a from A a WHERE TYPE(a) = A"); 
      List<?> queryResult = query.getResultList(); 
      entityManager.getTransaction().commit(); 
      System.out.println(queryResult.size()); 
     }finally { 
      if(entityManagerFactory != null) { 
       entityManagerFactory.close(); 
      } 
     } 
    } 
} 

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"> 
    <persistence-unit name="type-operator-nonsense" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <class>de.richtercloud.type.operator.nonsense.A</class> 
    <properties> 
     <property name="javax.persistence.jdbc.url" value="jdbc:derby:/tmp/type-operator-nonsense"/> 
     <property name="javax.persistence.jdbc.user" value=""/> 
     <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/> 
     <property name="javax.persistence.jdbc.password" value=""/> 
     <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> 
     <property name="hibernate.hbm2ddl.auto" value="update"/> 
    </properties> 
    </persistence-unit> 
</persistence> 

с org.hibernate:hibernate-entitymanager:5.1.0.Final и org.apache.derby:derby:10.11.1.1

A является POJO, в этом примере, который не включает в себя наследование, которое не имеет значения для ограничение, которое я ожидаю (хотя было бы бессмысленно применять его, если нет наследования):

package de.richtercloud.type.operator.nonsense; 

import java.io.Serializable; 
import javax.persistence.Entity; 
import javax.persistence.Id; 

@Entity 
public class A implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String b; 
    @Id 
    private Long id; 

    public A() { 
    } 

    public A(Long id, String b) { 
     this.id = id; 
     this.b = b; 
    } 

    public void setB(String b) { 
     this.b = b; 
    } 

    public String getB() { 
     return b; 
    } 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
} 

Полный пример можно найти по адресу: https://github.com/krichter722/type-operator-nonsense.

+0

Я только что изучил эту проблему и нашел, что некоторые хотели поделиться с вами. ** Можете ли вы попробовать с .class вместо Type() «SELECT a from A a WHERE a.class = A» или создать репозиторий для класса сущностей A и получить доступ к вашему фактическому запросу с помощью типа -SELECT a из A a ГДЕ ТИП (a) = A ** – Shaan

+0

'ВЫБРАТЬ a из A a WHERE a.class = A' сбой с той же самой ошибкой, которая указывает на то, что это может быть ошибка спящего режима или бессмысленная обратная связь. Что вы подразумеваете под «репозиторием» - термином «jar' dependancy - speak maven? Если да, почему это должно иметь какое-то значение? –

+0

Я имею в виду JPA реплику и .class для спящего режима. Пожалуйста, ссылка может быть полезна вам http://stackoverflow.com/questions/4884249/java-jpa-query-with-specified-inherited-type – Shaan

ответ

0

TYPE() может использоваться только для наследования.

Является ли класс в сопоставлении наследования и A либо классом маршрута с @Inheritance, либо A расширяет класс с объявлением @Inheritance?

Пример.

@Inheritance 
@Entity 
public class Project 

@Entity 
public class DesignProject extends Project 

@Entity 
public class QualityProject extends Project 

@Entity 
public class SoftwareProject extends Project 

Теперь вы можете использовать TYPE()

SELECT p 
FROM Project p 
WHERE TYPE(p) = DesignProject OR TYPE(p) = QualityProject 
+0

Можете ли вы добавить ссылку или разработать. Почему это не упоминается в спецификации [JPA 2.1] (http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf?AuthParam=1459196694_4386929d6f1aa92ffdf995cd502e4d75)? И вы имеете в виду «корневой класс», верно? У меня возникают эти проблемы без участия наследования объектов, см. Обновленный вопрос для деталей. –

+0

Я могу вызвать проблему, сделав самый верхний класс в иерархии наследования «MappedSuperclass».Я не понимаю, что вы подразумеваете под именем '@ Inheritance', потому что есть значение по умолчанию' InheritanceType.SINGLE_TABLE', т. Е. Ваше утверждение имеет смысл только в том случае, если вы ссылаетесь на конкретную стратегию (и объясните, какие проблемы она вызывает). Я проверил этот вопрос со всеми тремя стратегиями. –

+0

Я имею в виду, что вы должны использовать его с сущностями в дереве наследования. @MappedSupperclass не является наследованием в этом случае. –

Смежные вопросы