2012-05-18 46 views
20

Tengo una clase simple de Entitly con los campos @EmbeddedId (Integer y String en clases separadas). Y uso los datos de Spring (org.springframework.data.jpa.repository.JpaRepository) para acceder a la base de datos (MySql), con el Id normal las consultas funcionan bien, tanto las generadas por Spring como las que escribí yo mismo. Con el EmbeddedId no logré crear la consulta correcta. Lo que quiero hacer es seleccionar todo el ID (uno de los campos de embeddedId para el que se produce alguna condición). Aquí tiene algunas muestras de código, tal vez alguien tendrá una idea de cómo resolverlo.
La clase de entidad:Usando @EmbeddedId con JpaRepository

@Entity 
@Table(name="table_name") 
public class EntityClass { 

    @EmbeddedId 
    private EmbeddedIdClass id; 
    private String someField; 
    //rest of implemetation 
} 

la clase EmbeddedId:

@Embeddable 
public class EmbeddedIdClass implements Serializable { 

public EmbeddedIdClass(Long id, String language) { 
    super(); 
    this.id = id; 
    this.language = language; 
} 

public UserAdTextId() {}   

@Column(name="ad_id", nullable=false) 
    private Integer id; 

    @Column(name="language_code", nullable=false) 
    private String language; 
    //rest of implemetation 
} 

y el repositorio:

@Transactional(readOnly=true) 
public interface MyRepository extends JpaRepository<EntityClass, EmbeddedIdClass> { 
    @Query("select distinct ad_id from EntityClass where userId = :userId and (/*here the conditions*/)") 
    public Page<Integer> findUserAdsWithSearchString(@Param("userId") Integer userId, @Param("searchString") String searchString, Pageable page); 
//rest of implemetation 
} 

no he encontrado ninguna documentación cómo crear los métodos para apoyar la @EmbeddedId, estaba probando muchos nombres de métodos diferentes, pero siempre recibo excepciones del analizador del método ...

Respuesta

10

Parece que su consulta está utilizando nombres de columna. Debe contener los nombres de propiedad, incluida la navegación en objetos incrustados. También hay una pregunta relacionada aquí en SO: How to write JPQL SELECT with embedded id?

select distinct id.id from EntityClass where userId = :userId and (...) 

La primera se refiere a atribuir idid de EntityClass (de tipo EmbeddedIdClass), y la segunda se refiere a la propiedad de idEmbeddedIdClass.

Además, asegúrese de que hay una propiedad de userId en.

+0

Es correcto, tengo que usar los nombres de campo y navegar a través de ellos, sin embargo, obtengo el resultado sql con cuenta seelct (distinct ...) ¿De dónde viene el conteo? el tipo de devolución es la página o la lista (estaba intentando ... – Mat

+0

La respuesta es correcta, otro problema que tenía era una paginabilidad ... parece que las consultas con distinct o group by cant manejan Pageable ... pena :( – Mat

21

(por Yosi Lev) Esto se puede hacer de la siguiente manera: Suponga que su entidad principal es:

@Entity 
@Table(name="JRULES_FLOW") 
public class JrulesFlow implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private JrulesFlowPK id; 

    @Column(name="NEXT_SEQ") 
    private int nextSeq; 

    @Column(name="REF_ID") 
    private String refId; 

    @Column(name="TASK_TYPE") 
    private String taskType; 

    @Column(name="VALUE_TO_FIND") 
    private String valueToFind; 
} 

Y la clase de PK es:

@Embeddable 
public class JrulesFlowPK implements Serializable { 
    //default serial version id, required for serializable classes. 
    private static final long serialVersionUID = 1L; 

    @Column(name="FLOW_ID") 
    private String flowId; 

    @Column(name="TASK_SEQ") 
    private long taskSeq; 
} 

El repositorio nombre del método de la APP shouls incluye el nombre del campo id en la clase principal seguida de la propiedad que desea consultar dentro de la clase PK:

public interface JrulesFlowRepository extends JpaRepository<JrulesFlow, 
     JrulesFlowPK> { // NOTE: put here both classes - also the pk class.. 
    public List<JrulesFlow> findByIdFlowId(String flowId); // Id - is the 
        // @EmbeddedId in JrulesFlow. FlowId is an attribute 
        // within JrulesFlowPK 
} 
+1

para columnas múltiples-- findByIdCol1AndIdCol2AndIdCol3 (String col1, String col2, String col3); funciona – Boo