Using IS NULL with JPQL? - eclipse

I have 2 Entity, Aluno and Matricula. I want return all Aluno without Matricula. To do this, I'm trying use IS NULL of JPQL but still could not do this work.
How can I do this ?
I'm trying this.
#Entity
public class Aluno{
#Id #GenerateValue
private Long id;
#OneToOne
private Matricula matricula
}
#Entity
public class Matricula{
#Id #GenerateValue
private Long id;
#OneToOne
private Aluno aluno;
}
//
public List<Aluno> getAlunosWithoutMatricula(){
String jpql = "SELECT a FROM Aluno a JOIN a.matricula mat WHERE mat IS NULL";
TypedQuery<Aluno> query = em.createQuery(jpql, Aluno.class);
return query.getResultList();
}

I solved the problem
here.
public List<Aluno> getAlunosWithoutMatricula(){
String jpql = "SELECT a FROM Aluno a WHERE (a.matricula IS NULL)";
TypedQuery<Aluno> query = em.createQuery(jpql, Aluno.class);
return query.getResultList();
}

Related

Named Query with List of object as input using JPA named query

Getting below QueryExecutionRequestException when I try to excecute update Named query using JPA repository.
org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations [update com.company.farmer.entity.FarmProducts p set p.isDeleted=:isDeleted where p.productId IN (:productIdsList_0, :productIdsList_1)]; nested exception is java.lang.IllegalStateException: org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations [update com.company.farmer.entity.FarmProducts p set p.isDeleted=:isDeleted where p.productId IN (:productIdsList_0, :productIdsList_1)]
Code:
#Repository
public interface FarmProductRepository extends JpaRepository<FarmProducts, Long> {
void deleteProduct(#Param("isDeleted") String isDeleted, #Param("productIdsList") List<Long> productIdsList);
}
#Override
public String deleteProductAndCategory(long categoryId, FarmProductIdsDTO farmProductIds) {
farmProductRepository.deleteProduct(FarmerProductCategoryConstants.DELETE_YES_FLAG, farmProductIds.getFarmProductIds());
return FarmerProductCategoryConstants.SUCCESS;
}
#Entity
#Table(name="farm_products")
#Getter
#Setter
#ToString(exclude= "productCategory")
#NoArgsConstructor
#AllArgsConstructor
#NamedQueries({#NamedQuery(name="FarmProducts.deleteProduct", query="update FarmProducts p set p.isDeleted=:isDeleted where p.productId IN (:productIdsList)") })
public class FarmProducts extends BaseModel {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FARM_PRODUCT_GENERATOR")
#SequenceGenerator(name = "FARM_PRODUCT_GENERATOR", sequenceName = "FARM_PRODUCT_GENERATOR_SEQ", allocationSize = 1)
#Column(name = "farm_product_id")
public Long productId;
#ManyToOne
#JoinColumn(name = "farm_product_category_id")
#JsonIgnoreProperties("products")
public ProductCategory productCategory;
#Column(name = "product_name")
public String product;
#Column(name = "is_deleted")
public String isDeleted;
}
I am trying to pass a list of productId to make the isDeleted as "N". But update functionality fails because of the QueryExecutionRequestException.
By default Spring Data treats all queries as SELECT statements. If you have an UPDATE (or DELETE) statement you have you have to apply de #Modifying annotation on the query.
See https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.modifying-queries

Composite key query in JPQL not generated correctly

I use spring data jpa and I use composite key
#Entity
#IdClass(SamplesPK.class)
public class Samples extends BaseEntity {
#Id
private String sampleLetter;
#Embedded
private TestSamples testSamples;
#Id
#ManyToOne(optional=false)
#JoinColumns({
#JoinColumn(name = "sampling_id", referencedColumnName = "id"),
#JoinColumn(name = "sampling_year", referencedColumnName = "year")})
private Samplings sampling;
//get set
}
public class SamplesPK implements Serializable {
private SamplingsPK sampling;
private String sampleLetter;
public SamplesPK(SamplingsPK sampling, String sampleLetter) {
this.sampling = sampling;
this.sampleLetter = sampleLetter;
}
//get set
}
#Entity
#IdClass(SamplingsPK.class)
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {
#Id
private Integer year;
#Id
#GeneratedValue
private Integer id;
#OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Samples> samples = new ArrayList<>();
//get set
}
public class SamplingsPK implements Serializable {
private int year;
private Integer id;
public SamplingsPK(int year, Integer id) {
this.id = id;
this.year = year;
}
}
I try to do search sample with composite key
#Query(value = "select s from Samples s Join fetch s.sampling sp Join fetch sp.product p Join fetch p.productType Join Fetch s.testSamples.compressionTest where s.id=:id and s.year=:year and s.sampleLetter=:sampleLetter and sp.id=:id and sp.year=:year")
public Samples findSamplesWithFullProductAndTest(#Param("id") Integer id, #Param("year") Integer year, #Param("sampleLetter") String sampleLetter);
I get this error
java.lang.IllegalArgumentException: Parameter value [2] did not match
expected type [com.lcm.model.SamplesPK (n/a)]
Edit,
I modified query to
select s from Samples s Join fetch s.sampling sp Join fetch sp.product p Join fetch p.productType Join Fetch s.testSamples.compressionTest where s.sampling.id=:id and s.sampling.year=:year and s.sampleLetter=:sampleLetter and sp.id=:id and sp.year=:year
but I get this error
org.postgresql.util.PSQLException: ERROR: operator does not exist:
record = integer Indice : No operator matches the given name and
argument type(s). You might need to add explicit type casts.
Generated query is
select
samples0_.sample_letter as sample_l1_20_0_,
samples0_.sampling_id as sampling0_20_0_,
samplings1_.id as id2_21_1_,
samplings1_.year as year3_21_1_,
products2_.id as id2_15_2_,
producttyp3_.id as id1_16_3_,
compressio4_.id as id1_3_4_,
samples0_.sampling_id as samplin27_20_0_,
samples0_.sampling_year as samplin28_20_0_,
samples0_.compression as compres18_20_0_,
samples0_.compression_number as compres19_20_0_,
samples0_.compression_test_id as compres29_20_0_,
samplings1_.available_for_test as availabl4_21_1_,
samplings1_.dtype as dtype1_21_1_,
products2_.created_at as created_3_15_2_,
products2_.updated_at as updated_4_15_2_,
products2_.name_en as name_en5_15_2_,
products2_.dtype as dtype1_15_2_,
producttyp3_.created_at as created_2_16_3_,
producttyp3_.updated_at as updated_3_16_3_,
producttyp3_.name_en as name_en4_16_3_,
compressio4_.created_at as created_2_3_4_,
compressio4_.updated_at as updated_3_3_4_
from
permacon.samples samples0_
inner join
permacon.samplings samplings1_
on samples0_.sampling_id=samplings1_.id
and samples0_.sampling_year=samplings1_.year
inner join
permacon.products products2_
on samplings1_.product_id=products2_.id
inner join
permacon.product_types producttyp3_
on products2_.product_type_id=producttyp3_.id
inner join
permacon.compressions compressio4_
on samples0_.compression_test_id=compressio4_.id
where
(
samples0_.sampling_id, samples0_.sampling_year
)=?
and samplings1_.year=?
and samples0_.sample_letter=?
and samplings1_.id=?
and samplings1_.year=?
Edit 2
#MappedSuperclass
public abstract class BaseEntity {
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
//get set...
}
Inheritance is used because I have two table who extends Samplings
you year field is a int put int instead of Integer in your
findSamplesWithFullProductAndTest
method

JPA Criteria subqueries combined with disjunction

i have a little problem with JPA criteria API. I have one Entity:
#Entity
#Table(name = "PERSON")
public class Person implements Serializable
{
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "person_gen")
#Column(name = "ID")
private Long id;
#Column(name = "NAME")
private String name;
#Column(name = "AGE")
private Integer = age;
public Long getId()
{
return this.id;
}
public String getName()
{
return this.name;
}
public Integer getAge()
{
return this.age;
}
}
And now i want make a query similar to this:
select * from Person where
(Person.Id) in (select Person.Id from Person where Person.Id = 15625) or
(Person.Id) in (select Person.Id from Person where Person.Name = 'Name') or
(Person.Id) in (select Person.Id from Person where Person.Age = 28)
There are some subqueries with an 'or' statement. How to do this with JPA criteria query? I have tried many things an it does not work.
Thanks in advance.
Your particular query really is unnecessarily complex. Your IN predicates can all be removed and replaced by the following, much simpler predicates:
SELECT *
FROM Person
WHERE Id = 12625
OR Name = 'Name'
OR Age = 28
This should be much simpler to translate to a JPA criteria query.

JPA with hibernate implementation is generating wrong named query

I configured JPA with spring. I am using spring 4.
I have an entity
#Entity
#NamedQueries({
#NamedQuery(name="PartnerCourseMapping.findByPartnerCourseIdAndHandlerName", query="select pm from PartnerCourseMapping pm where pm.partnerCourseId=:partnerCourseId and pm.handlerName=:handlerName")
})
#Table(name="PARTNER_COURSE_MAPPING")
public class PartnerCourseMapping implements Serializable {
private static final long serialVersionUID = 1L;
#Id
protected Long id;
#Column(name="COURSE_ID")
protected Long courseId;
#Column(name="PARTNER_COURSE_ID")
protected String partnerCourseId;
#Column(name="PARTNER_ID")
protected Integer partnerId;
#Column(name="PRODUCT_TYPE")
protected String productType;
#Column(name="HANDLER_NAME")
protected String handlerName;
//getters and setters
}
I have another entity which i defined like below
#Entity
#NamedNativeQueries({
#NamedNativeQuery(
name="ExternalCourse.findExternalCourseMappingByLearningSessionGuid",
query="SELECT PCM.*, LE.id AS LearnerEnrollmentId, LE.LEARNER_ID AS LearnerId "
+ "FROM LEARNINGSESSION LS "
+ "INNER JOIN LEARNERENROLLMENT LE ON LE.ID = LS.ENROLLMENT_ID "
+ "INNER JOIN PARTNER_COURSE_MAPPING PCM ON PCM.COURSE_ID = LE.COURSE_ID "
+ "WHERE LS.LEARNINGSESSIONGUID = :learningSessionGuid",
resultSetMapping="externalCourseMapping"
)
})
#SqlResultSetMappings({
#SqlResultSetMapping(
name="externalCourseMapping",
classes = {
#ConstructorResult(targetClass = ExternalCourse.class,
columns={
#ColumnResult(name = "ID", type=Long.class ),
// remaing ColumnResult
}
)
}
)
})
public class ExternalCourse extends PartnerCourseMapping /*implements Serializable*/ {
private Long learnerEnrollmentId;
private Long learnerId;
//default constructor
public ExternalCourse(Long id, Long courseId, String partnerCourseId, Integer partnerId, String productType,
String handlerName, Long learnerEnrollmentId, Long learnerId) {
this.id = id;
// remaing values
}
//getters and setters for learnerEnrollmentId and learnerId
}
Now I query PartnerCourseMapping.findByPartnerCourseIdAndHandlerName
TypedQuery<PartnerCourseMapping> query = entityManager.createNamedQuery("PartnerCourseMapping.findByPartnerCourseIdAndHandlerName", PartnerCourseMapping.class);
query.setParameter("partnerCourseId", paernerCourseId);
query.setParameter("handlerName", handlerName);
return getResult(query);
protected T getResult(TypedQuery<T> query) {
List<T> list = query.getResultList();
return CollectionUtils.isEmpty(list) ? null : list.get(0);
}
Hibernate is generating exception that
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
...
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'learnerEnrollmentId'.
When I debug then I saw hibernate is generating query like below
select partnercou0_.id as id2_13_,
partnercou0_.COURSE_ID as COURSE_I3_13_,
partnercou0_.HANDLER_NAME as HANDLER_4_13_,
partnercou0_.PARTNER_COURSE_ID as PARTNER_5_13_,
partnercou0_.PARTNER_ID as PARTNER_6_13_,
partnercou0_.PRODUCT_TYPE as PRODUCT_7_13_,
partnercou0_.learnerEnrollmentId as learnerE8_13_,
partnercou0_.learnerId as learnerI9_13_,
partnercou0_.DTYPE as DTYPE1_13_
from PARTNER_COURSE_MAPPING partnercou0_ where partnercou0_.PARTNER_COURSE_ID=? and partnercou0_.HANDLER_NAME=?
I want to ask that why hibernate is including learnerEnrollmentId and learnerId column? I am passing the query name and query. If I refactor my code like below then I get the correct result
#Entity
#NamedNativeQueries({
#NamedNativeQuery(
name="ExternalCourse.findExternalCourseMappingByLearningSessionGuid",
...
resultSetMapping="externalCourseMapping"
)
})
#SqlResultSetMappings({
#SqlResultSetMapping(
name="externalCourseMapping",
classes = {
..
}
)
})
public class ExternalCourse implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Long id;
private Long courseId;
private String partnerCourseId;
private Integer partnerId;
private String productType;
private String handlerName;
private Long learnerEnrollmentId;
private Long learnerId;
//default constructor
//constructor with all parameters
//getters and setters
}
Why I am getting exception when I am extending class? I am passing the query name. Why ?
Thanks

Query an embedded collection inside an entity using Datanucleus and mongodb

I was trying to query a embedded collection inside an entity using a query similar to the following:
Query q = em.createQuery("SELECT u FROM User u , in (u.addresses) a
WHERE a.state='xx'");
The query didn't return any result nor did it throw any error. I am using Datanucleus and MongoDb. Does Datanucleus have any limitation on such queries?
And the entity looked like:
public class User{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
protected long id;
#ElementCollection
protected List<Address> addresses;
public User(){
}
...
#Embeddable
public class Address {
private String street;
private String city;
private String state;
private Integer zip;
public Address(){
}
...