2009-12-29 8 views
11

Diciamo che abbiamo questa classe con annotazione JPA, con una proprietà di tipo Elenco. Questo codice funziona correttamente.Come interrogare una proprietà di tipo Elenco <String> in JPA

@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; 
    ... 
} 

Esiste un modo per interrogare l'elenco di Famiglie che contengono l'elemento "yyy"? Cioè, qualcosa di simile a:

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

risposta

16

nota che si sta utilizzando Hibernate caratteristica specifica CollectionOfElements. Questo non è strettamente JPA. È possibile HQL specifica elements funzione per fare questo:

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

Ecco un esempio di lavoro:

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(); 
      } 
     } 
    } 

Per ragioni di completezza, 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

MEMBRO DEL clausola JPQL:

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"}); 
Problemi correlati