Spring data JPA - Exclude ID column from one entity parameter - java

I have two entities :
#Entity
public class Car {
#Id
private Long id;
#OneToOne
private Engine engine;
}
and the other one :
#Entity
public class Engine {
#Id
private Long id;
#Column
private String value1;
#Column
private String value2;
}
In my jpaRepositoy interface, i would like to do :
public interface CarRepository extends JpaRepository<Car, Long> {
public Car findByEngine(Engine engine);
}
But this method doesn't return my entity stored, because I created my Engine doing :
Engine engine = new Engine("someValue", "someValue");
without setting engine's id which is stored in database.
So I would like to know if it is possible exclude a column like id ?
If no, is the only way to do this is :
#Query("SELECT c FROM Car c WHERE c.engine.value1 = :value1 and c.engine.value2 = :value2")
findByEngine(#Param("value1") String value1, #Param("value2") String value2)
?
Related question : If I have OneToMany relationship instead of OneToOne, like
#Entity
public class Car {
#Id
private Long id;
#OneToMany
private List<Engine> engines;
}
How can I do this request to have something like (still without id column) :
public Car findByEngines(List<Engine> engines);
Thanks a lot !

This #Query("SELECT c FROM Car c WHERE c.value1 = :value1 and c.value2 = :value2") is not correct jpql query for your scenario, You do not have value1 and value2 in Car entity.
Correct one would be:
#Query("SELECT c FROM Car c WHERE c.engine.value1 = :value1 and c.engine.value2 = :value2").
You can try this method Name, I think that will work:
findByEngineValue1AndEngineValue2(String value1, String value2)
but for list one, i do not think you can make it up with just method name.

Related

how to map native sql query to Entity

lets say I have the following Entities
#Entity
public class Person{
private int id;
private String firstName;
private String lastName;
#OneToOne
private B b;
...
}
#Entity
public class B{
private int id;
private String x;
private String y;
...
}
What I want to do is create a SELECT query from a join that returns columns from multiple tables. From the resultset I want to create Objects of Entity Person, process them and then persist them. Something like this
List<Person> list = entityManager.createNativeQuery("SELECT p.firstName, p.lastName, st.entityB FROM someTable st JOIN Person p ON p.lastName = st.lastName").getResultList()
In the statement "someTable" is an unmanaged class, so there is no Entity class for that but it has a column with a reference to the Entity B.
This statement doesnt work but in my current solution I am just returning List<Object[]>. From there I could create a Person but would need to resolve the B Entity because I only get scalar types. Is there a cleaner way somehow, so that I could directly get a List of type Person and also the B Entity is resolved?

How to search with JpaRepository and nested list of objects?

Description
There is a PersonRepository and Person entity,
Person class contains List<Qualification>. Qualification class has 3 simple fields.
I have tried to add #Query annotation on custom method and use JPQL to get the results, but Qualification class fields were not available for manipulation in JPQL as it repository itself contains List<Qualification> instead of just a simple field of Qualification.
How can I search by these Qualification's nested fields?
Query
Now I need to find list of person entity where qualification's experienceInMonths is greater than 3 and less than 9 AND qualification's name field = 'java'.
Code
Person.java
#Data
#Entity
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
#NotEmpty
#Size(min = 2)
private String name;
#NotEmpty
#Size(min = 2)
private String surname;
#ElementCollection(targetClass = java.util.ArrayList.class, fetch = FetchType.EAGER)
private List<Qualification> qualifications = new ArrayList<>();
}
PersonRepository.java
#Repository
public interface PersonRepository extends JpaRepository<Person, String> {
}
Qualification.java
#Data
#AllArgsConstructor
public class Qualification implements Serializable {
#Id #GeneratedValue
private String id;
private String name;
private String experienceInMonths;
}
EDIT: not duplicate of this post, as here is the collection of nested objects. Not just single reference.
First, change experienceInMonths from String to int (otherwise you can not compare the string with the number). Then you can try to use this 'sausage':
List<Person> findByQualifications_experienceInMonthsGreaterThanAndQualifications_experienceInMonthsLessThanAndName(int experienceGreater, int experienceLess, String name);
Or you can try to use this pretty nice method:
#Query("select p from Person p left join p.qualifications q where q.experienceInMonths > ?1 and q.experienceInMonths < ?2 and q.name = ?3")
List<Person> findByQualification(int experienceGreater, int experienceLess, String name);
W can use ‘_’ (Underscore) character inside the method name to define where JPA should try to split.
In this case our method name will be
List<Person> findByQualification_name(String name);

Spring Data Projection with OneToMany returns too many results

I have a JPA entity (Person) with onetomany relation (ContactInfo).
#Entity
public class Person {
#Id
#GeneratedValue
private Integer id;
private String name;
private String lastname;
private String sshKey;
#OneToMany(mappedBy = "personId")
private List<ContactInfo> contactInfoList;
}
#Entity
public class ContactInfo {
#Id
#GeneratedValue
private Integer id;
private Integer personId;
private String description;
}
I've defined a projection interface that includes this onetomany relation as described here.
public interface PersonProjection {
Integer getId();
String getName();
String getLastname();
List<ContactInfo> getContactInfoList();
}
public interface PersonRepository extends JpaRepository<Person,Integer> {
List<PersonProjection> findAllProjectedBy();
}
When I retrieve the data with findAllProjectedBy the result contains too many rows. It looks like the returned data is the result of a join query similar to:
select p.id, p.name, p.lastname, ci.id, ci.person_id, ci.description
from person p
join contact_info ci on ci.person_id = p.id
For example for this data set:
insert into person (id,name,lastname,ssh_key) values (1,'John','Wayne','SSH:KEY');
insert into contact_info (id, person_id, description) values (1,1,'+1 123 123 123'), (2,1,'john.wayne#west.com');
The findAllProjectedBy method returns 2 objects (incorrectly) and the standard findAll returns 1 object (correctly).
Full project is here
I've done some debugging and it seems that the problem is with the jpa query.
The findAll method uses this query:
select generatedAlias0 from Person as generatedAlias0
The findAllProjectedBy uses this query:
select contactInfoList, generatedAlias0.id, generatedAlias0.name, generatedAlias0.lastname from Person as generatedAlias0
left join generatedAlias0.contactInfoList as contactInfoList
Does anyone know how to fix this invalid behaviour?
A quick fix for this problem is described here:
https://jira.spring.io/browse/DATAJPA-1173
You need to describe one of the single projection attributes with a #Value annotation. For the example posted above you will end up with:
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
public interface PersonProjection {
#Value("#{target.id}")
Integer getId();
String getName();
String getLastname();
List<ContactInfo> getContactInfoList();
}

JPQL - How can I get an extra param inside my entity?

I am new to JPQL and I am trying to get an extra parameter that is not in the entity, but I am not finding how to do it.
Through searched here in the forum I found out that some uses a DTO for it, but I am not knowing how to apply that.
Here is my entity:
#Entity
#Table(name = "person")
public class Person implements Serializable {
private int id;
private String name;
private String email;
private int age;
...
}
And my JPQL:
SELECT COUNT(a.name) as countOfNames, a FROM Person a WHERE a.name like :name
How can I get the countOfNames result inside of myentity object since it is not a column?
The simplest way is to use a constructor expression
package com.entites
public class PersonDto {
private Person person;
private Integer countOfNames;
public PersonDto(Person person, Integer countOfNames) {
this.person = person;
this.countOfNames = countOfNames;
}
}
select new com.entites.PesronDto(a, count(a.name))
from Person a
where a.name like :name

How Join hibernate Value objects using HQL query?

Hi i'm New to write HQL Query please help me.....
my Hibernate have three ValueObjects ie.
#Entity
#Table(name="user")
public class UserVO {
#Id
#Column(name="S_ID")
private String s_id;
#Column(name="FIRSTNAME")
private String firstName;
private String email;
}
CourseVO class
#Entity
#Table(name="course")
public class CourseVO
{
#Id
#Column(name="S_ID")
public String s_id;
#Column(name="NAME")
public String name;
}
Skillset VO
#Entity
#Table(name="skillset")
public class SkillsetVO
{
#Id
#Column(name="S_ID")
public String s_id;
#Column(name="COURSE_ID")//Foreign Key "USER"
public String course_id;
#Column(name="USER_ID")//Foreign key "COURSE"
public String user_id;
#Column(name="TEACH_EXP")
public String teach_Exp;
}
Now How to get Values of FirstName,NAME,TEACH_EXP values using EMAIL of USER table using HQL query
If you want to use join syntax in HQL you must work out your mapping accordingly as joins are enabled by mapping.
#Entity class A { #OneToMany private List<B> bs; }
#Entity class B { #Basic int n; }
Enables
select b from A a inner join a.b where a = :id
But with your mapping this is not possible. Also bear in mind that in terms of efficiency most of the RDBMs will perform an inner join on a where a.id = b.id.
select u.firstName, c.name, s.teach_Exp
from UserVO u, CourseVO c, SkillsetVO s
where
u.s_id = s.user_id
and c.s_id = s.course_id
and u.email = :email
But I think that you must review you association. Since looks to me that SkillsetVO.user_id should be SkillsetVO.User (an association to a UserVO entity and same for CourseVO).

Categories