Reputation: 135
@Entity
@EntityListeners(AuditingEntityListener.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TIPO_CONTRATO", discriminatorType = DiscriminatorType.STRING)
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
public class Contrato extends AuditorEntity implements Serializable, Clonable {
@Column(name = "CIF_NIF")
@JsonView(Views.Buscador.class)
@JsonProperty("cifNif")
private String cifNif;
@Column(name = "NOMBRE_SOCIEDAD_PERSONA")
@JsonView(Views.Buscador.class)
private String nombreSociedadPersona;
}
And i have this Embeddable class called CuentaBancaria
from Contrato
table:
@Embeddable
public class CuentaBancaria implements Serializable {
private static final long serialVersionUID = 6835775213299596371L;
@Column(name = "TITULAR_CUENTA")
@JsonView(Views.Completo.class)
private String titularCuenta;
}
In ContratoRepository
i'm trying doing a JPA Query finding the "titularCuenta
" field of Cuenta Bancaria finding by the cifNif
field of Contrato
. But it's not working. What can i do to solve this?
@Query(value="SELECT c.CuentaBancaria.titularCuenta FROM Contrato c WHERE c.cifNif= ?1 AND c.nombreSociedadPersona IS NOT NULL AND ROWNUM = 1")
public String getNombreLegalCliente(String cifNif);
The error which is throwing:
Caused by: org.hibernate.QueryException: could not resolve property: CuentaBancaria of: com.xxxx.Contrato
Upvotes: 0
Views: 1082
Reputation: 81
Yes, since your class [ CuentaBancaria ] is annotated with @Embeddable, it needs to be embedded in the parent class in this case [ Contrato ] with @Embedded.
Then, harnessing Spring Data JPA query Lookup strategies, you can access property fields of your embedded class with ease or you could still go by the @Query() approach Query lookup Strategy from Spring documentation
Sample demo code with your problem with a minimal implementation:
Entity-Class
--------------
@Entity
public class Contrato{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long contratoId;
@Column(name = "CIF_NIF")
private String cifNif;
@Column(name = "NOMBRE_SOCIEDAD_PERSONA")
private String nombreSociedadPersona;
//we call the embeddable class in this parent class with @Embedded annotation
@Embedded
private CuentaBancaria cuentaBancaria
}
Embeddable-Class
-----------------
@Embeddable
public class CuentaBancaria{
@Column(name = "TITULAR_CUENTA")
private String titularCuenta;
}
Now in your ContratoRepository class, we could have
@Repository
public interface ContratoRepository extends CrudRepository<Contrato, Long> {
Optional<Contrato> findByCuentaBancariaTitularCuenta(String cifNif);
}
which interprets to JPQL snippet:
c.cuentaBancaria.titularCuenta FROM Contrato c WHERE c.cifNif= ?1
NOTE: Notice the query method name matches the exact names in the classes and their corresponding fields, preceded by findBy
Upvotes: 0
Reputation: 14816
You're missing CuentaBancaria
field in Contrato
class. That's why JQL complains.
Add the field in the class with @Embedded
annotation:
public class Contrato extends AuditorEntity implements Serializable, Clonable {
@Embedded
private CuentaBancaria cuentaBancaria;
}
And fix the JQL expression to:
@Query(value="SELECT c.cuentaBancaria.titularCuenta FROM Contrato c WHERE c.cifNif= ?1 AND c.nombreSociedadPersona IS NOT NULL AND ROWNUM = 1")
public String getNombreLegalCliente(String cifNif);
Upvotes: 2