2009-12-29 50 views
11

假設我們有此JPA註釋的類,並具有List類型的屬性。此代碼目前正在正常工作。如何查詢JPA中的列表<String>的屬性

@Entity 
public class Family { 
    ... 
    @CollectionOfElements(targetElement=java.lang.String.class) 
    @JoinTable(name = "elements_family", 
     joinColumns = @JoinColumn(name = "idFamily") 
    ) 
    @Column(name = "element", nullable = false) 
    private List<String> elements; 
    ... 
} 

是否有任何方式來查詢包含元素「yyy」的家庭列表?也就是說,這樣的:在JPQL子句

Query query = getEntityManager().createQuery("select f FROM Family f WHERE element = :element"); 
query.setParameter("element", "yyy"); 
return query.getResultList(); 

回答

16

請注意,您在使用Hibernate特定功能CollectionOfElements。這不是嚴格的JPA。您可以HQL具體elements功能來做到這一點:

select f from Family f WHERE :element in elements(f.elements) 

這裏是一個工作示例:

import org.hibernate.annotations.CollectionOfElements; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.EntityTransaction; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.Persistence; 
import javax.persistence.Query; 
import java.util.Arrays; 
import java.util.List; 

    @Entity 
    public class Family { 
     @Id 
     int id; 

     String name; 

     @CollectionOfElements(targetElement = java.lang.String.class) 
     @JoinTable(name = "elements_family", 
       joinColumns = @JoinColumn(name = "idFamily") 
     ) 
     @Column(name = "element", nullable = false) 
     public List<String> elements; 

     public static void main(String[] args) throws Exception { 
      EntityManagerFactory emf = 
       Persistence.createEntityManagerFactory("mysql"); 
      EntityManager em = emf.createEntityManager(); 
      try { 

       Family f1 = new Family(); 
       f1.id = 1; 
       f1.name = "Happy"; 

       f1.elements = Arrays.asList("foo", "bar", "yyy", "zzz"); 

       Family f2 = new Family(); 
       f1.id = 2; 
       f2.name = "Disfunctional"; 
       f2.elements = Arrays.asList("foo", "bar", "yyy", "xxx"); 

       EntityTransaction tx = em.getTransaction(); 
       tx.begin(); 
       em.persist(f1); 
       em.persist(f2); 
       tx.commit(); 
       Query query = em.createQuery(
        "select f from Family f WHERE :element in elements(f.elements)"); 
       query.setParameter("element", "bar"); 
       List list = query.getResultList(); 
       assert list.size() == 2; 

      } finally { 
       em.close(); 
       emf.close(); 
      } 
     } 
    } 

爲了完整起見,persistence.xml中

<persistence-unit name="mysql" transaction-type="RESOURCE_LOCAL"> 
    <class>jpa.Family</class> 
    <properties> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> 
     <property name="hibernate.connection.driver_class" 
          value="com.mysql.jdbc.Driver"/> 
     <property name="hibernate.connection.url" value="jdbc:mysql://localhost/test"/> 
     <property name="hibernate.connection.username" value="test"/> 
     <property name="hibernate.connection.password" value="test"/> 
     <property name="hibernate.show_sql" value="true"/> 
     <property name="hibernate.format_sql" value="true"/> 
     <property name="hibernate.max_fetch_depth" value="3"/> 
     <property name="hibernate.bytecode.use_reflection_optimizer" value="true"/> 
     <property name="hibernate.archive.autodetection" value="true"/> 
     <property name="hibernate.cache.use_second_level_cache" value="true"/> 
     <property name="hibernate.generate_statistics" value="true"/> 
     <property name="hibernate.hbm2ddl.auto" value="create"/> 
    </properties> 
</persistence-unit> 
15

成員:

Query query = getEntityManager().createQuery("select f FROM Family f WHERE :element MEMBER OF f.element"); 
query.setParameter("element", "yyy"); 
return query.getResultList(); 
4
List<Family> found = getHibernateTemplate().find(
"from Family as f join f.elements as e where e = ?", 
new Object[]{"yyy"});