I'm trying to create a spring boot application, and I would like to set up a research feature.
What I've done so far :
I have two classes, Person.java and House.java with a OneToOne
relationship between these two classes. I'd like to create a research function which allows me to find a Person depending on the House properties. For exemple find all persons who have houses with zipcode "45000" and city "ORLEANS". For this I've declared a function in my repository findByHouseZipcodeAndCity
.
Now, the problem is that my House entity has about 15 properties, and I want to perform researches with any of these 15 properties : zipcode only, zipcode and city, city and surface... which makes a lot of combinations, and I don't want to create findBy
methods for each combination.
I've tried to give as a parameter to my findBy
a House object which will contain the search criterias. This is not working as hibernate throws me this error : object references an unsaved transient instance - save the transient instance before flushing
. The problem is that I'm creating an instance of a House, I fill it with my search criterias, and I use it for my findBy, but I found the findBy makes a flush()
, while the House entity is not saved (And I don't want it to be saved since it's only for a search).
I've found solutions like using JPA Criterias, but I'd like to know if I can perform my search just by using an entity as a parameter for a findBy method.
Thank you in advance for your help
PersonRepository.java
@Repository
public interface PersonRepository extends JpaRepository<Person, Long>{
List<Person> findByHouseZipcodeAndHouseCity(String zipcode, String city);
List<Person> findByHouse(House house);
}
Person.java
@Entity
public class Person{
@Id
@SequenceGenerator(name = "INFO_ACTION_SEQ", sequenceName = "INFO_ACTION_SEQ")
@GeneratedValue(generator = "INFO_ACTION_SEQ", strategy = GenerationType.AUTO)
@Column(name = "ID_PERSON", columnDefinition = "INTEGER")
private Integer id;
private String name;
private String surname;
@OneToOne(cascade = CascadeType.ALL)
private House house;
}
House.java
@Entity
public class House{
@Id
@SequenceGenerator(name = "INFO_ACTION_SEQ", sequenceName = "INFO_ACTION_SEQ")
@GeneratedValue(generator = "INFO_ACTION_SEQ", strategy = GenerationType.AUTO)
@Column(name = "ID_HOUSE", columnDefinition = "INTEGER")
private Integer id;
private String city;
private String street:
private String zipcode;
private String country;
// Other properties...
}
You could use query by example, a user-friendly querying technique that allows dynamic query creation and does not require you to write queries at all.
Consider the following entity:
@Data
@Entity
public class Person {
@Id
private String id;
private String firstname;
private String lastname;
private Address address;
}
To search all persons with a given name, you can use:
Person person = new Person();
person.setFirstname("Dave");
Example<Person> example = Example.of(person);
Iterable<Person> searchResult = repository.findAll(example);
And, if you need to search for a single person, use:
Person searchResult = repository.findOne(example);