How to write this query in HQL? - java

I'm learning Hibernate and I'm having trouble writing queries against many-to-many tables. I need to translate this into the HQL
SELECT books.id,books.name,books.year,books.priceRent,books.priceSell,books.amount, author.full_name,genre.genre_name FROM books
INNER JOIN book_author ON books.id = book_author.book_id
INNER JOIN author ON book_author.author_id = author.author_id
INNER JOIN book_genre ON books.id = book_genre.genre_id
INNER JOIN genre ON book_genre.genre_id = genre.genre_id
I tried to write like this:
FROM Book b LEFT JOIN b.author LEFT JOIN b.genre
But it gives an error:
java.sql.SQLSyntaxErrorException: Unknown column 'genre3_.id' in 'on clause'
At the same time, I already have all the table entities
Here is Author Entity
#Entity
#Table(name = "author")
public class Author {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "author_id")
private Integer id;
#Column(name = "full_name")
private String name;
public Author(String name) {
this.name = name;
}
public Author() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Book> getBookList() {
return bookList;
}
public void setBookList(List<Book> bookList) {
this.bookList = bookList;
}
#ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH})
#JoinTable(name = "book_author",joinColumns = #JoinColumn(name = "author_id"),inverseJoinColumns = #JoinColumn(name = "book_id"))
private List<Book> bookList;
#Override
public String toString() {
return "Author{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
Here is Genre Entity
#Entity
#Table(name = "genre")
public class Genre {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "genre_id")
private Integer id;
#Column(name = "genre_name")
private String genre;
#ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH})
#JoinTable(name = "book_genre",joinColumns = #JoinColumn(name = "genre_id"),inverseJoinColumns = #JoinColumn(name = "book_id"))
private List<Book> bookList;
public Genre(){}
public List<Book> getBookList() {
return bookList;
}
public void setBookList(List<Book> bookList) {
this.bookList = bookList;
}
public Genre(String genre) {
this.genre = genre;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
#Override
public String toString() {
return "Genre{" +
"id=" + id +
", genre='" + genre + '\'' +
'}';
}
}
Here is Book Entity
#Entity
#Table(name = "books")
public class Book {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#Column(name = "name")
private String name;
#Column(name = "year")
private String year;
#Column(name = "priceRent")
private Integer priceRent;
#Column(name = "priceSell")
private Integer priceSell;
#Column(name = "amount")
private Integer amount;
#ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH})
#JoinTable(name = "book_author",
joinColumns = #JoinColumn(name = "id"),
inverseJoinColumns = #JoinColumn(name = "author_id"))
private List<Author> authorList;
#ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH})
#JoinTable(name = "book_genre",
joinColumns = #JoinColumn(name = "id"),
inverseJoinColumns = #JoinColumn(name = "genre_id"))
private List<Genre> genreList;
public Book() {
}
public Book(String name, String year, Integer priceRent, Integer priceSell, Integer amount) {
this.name = name;
this.year = year;
this.priceRent = priceRent;
this.priceSell = priceSell;
this.amount = amount;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public Integer getPriceRent() {
return priceRent;
}
public void setPriceRent(Integer priceRent) {
this.priceRent = priceRent;
}
public Integer getPriceSell() {
return priceSell;
}
public void setPriceSell(Integer priceSell) {
this.priceSell = priceSell;
}
public Integer getAmount() {
return amount;
}
public void setAmount(Integer amount) {
this.amount = amount;
}
public List<Author> getAuthorList() {
return authorList;
}
public void setAuthorList(List<Author> authorList) {
this.authorList = authorList;
}
public List<Genre> getGenreList() {
return genreList;
}
public void setGenreList(List<Genre> genreList) {
this.genreList = genreList;
}
#Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", year=" + year +
", priceRent=" + priceRent +
", priceSell=" + priceSell +
", amount=" + amount +
'}';
}
}

Related

H2 ERROR: Referential integrity constraint violation - Hibernate one to one mapping

I have two entity (Instructor, InstructorDetail) which have one to one relation.
instructor_detail_id of Instructor entity has a foreign key to the id column of InstructorDetail. So, according to my requirement, when an Instructor is deleted, corresponding instructorDetail also needs to be deleted, but not the vice versa. Now, when I am trying to delete an instructorDetail, it is throwing the referencial integrity constraint error.
Note: I am using H2 db.
Following are the code snippets.
Instructor -
import javax.persistence.*;
#Table(name="instructor")
#Entity
public class Instructor implements IdentityMarker<Integer>{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="instructor_id")
private int id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "instructor_detail_id")//, referencedColumnName = "id")
private InstructorDetail instructorDetail;
public Instructor(){
}
public Instructor(String name, String email) {
this.name = name;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public InstructorDetail getInstructorDetail() {
return instructorDetail;
}
public void setInstructorDetail(InstructorDetail instructorDetail) {
this.instructorDetail = instructorDetail;
}
public Integer getReference() {
return id;
}
public void setReference(Integer id){ this.id = id;}
#Override
public String toString() {
return "Instructor{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", instructorDetail=" + instructorDetail +
'}';
}
}
InstructorDetail -
import javax.persistence.*;
#Table(name="instructor_detail")
#Entity
public class InstructorDetail implements IdentityMarker<Integer>{
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name="youtube_link")
private String youtubeLink;
#Column(name="hobby")
private String hobby;
#OneToOne(cascade = {
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.REFRESH
},
mappedBy = "instructorDetail")
// this bi-directional relationship enables us to get the instructor when an instructionDetail is loaded.
private Instructor instructor;
public InstructorDetail(){
}
public InstructorDetail(String youtubeLink, String hobby){
this.youtubeLink = youtubeLink;
this.hobby = hobby;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getYoutubeLink() {
return youtubeLink;
}
public void setYoutubeLink(String youtubeLink) {
this.youtubeLink = youtubeLink;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Instructor getInstructor() {
return instructor;
}
public void setInstructor(Instructor instructor) {
this.instructor = instructor;
}
public Integer getReference() {
return id;
}
public void setReference(Integer id){ this.id = id;}
#Override
public String toString() {
return "InstructorDetail{" +
"id=" + id +
", youtubeLink='" + youtubeLink + '\'' +
", hobby='" + hobby + '\''+
'}';
}
#PreRemove
private void preRemove() {
System.out.println("pre remove call");
instructor.setInstructorDetail(null);
}
}
Following is the client code
private static void deleteInstructorDetail(){
InstructorDetailDao instructorDetailDao = new InstructorDetailDaoImpl();
InstructorDetail instructorDetail = instructorDetailDao.getInstructorDetail(2);
Instructor instructor = instructorDetail.getInstructor();
System.out.println("Instructor: " + instructor);
boolean b = instructorDetailDao.deleteInstructorDetail(instructorDetail);
assert b == true: "InstructorDetail is not deleted!";
System.out.println("Trying to load Instructor.. It should be deleted!");
InstructorDao instructorDao = new InstructorDaoImpl();
instructor = instructorDao.getInstructor(instructor.getId());
assert instructor != null: "Instructor also got deleted!";
}
Any help would be appreciated! Thanks in advance.

M:N table does not update

I have m:n relationship between User and Document. I am creating Document object, getting List - setDocumentsForUsers() and then I am persisting that object. Problem is, that document is created in my database, but not M:N relationship. What am I doing wrong? I tried to call flush after persisting, but it did not help at all.
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "first_name")
private String firstName;
private String surname;
private String email;
private String password;
#ManyToMany
#JoinTable(
name = "users_roles",
joinColumns = #JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(
name = "role_id", referencedColumnName = "id"))
private List<Role> roles;
#JsonIgnore
#ManyToMany
#JoinTable(
name="users_documents",
joinColumns = #JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(
name="document_id", referencedColumnName = "id"))
private List<Document> usersDocuments;
#OneToMany(mappedBy="user")
private List<Document> sharedDocuments;
public User() {
}
public User(String firstName, String surname, String email, String password) {
this.firstName = firstName;
this.surname = surname;
this.email = email;
this.password = password;
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public String getEmail() {
return email;
}
public void setEmail(String email){this.email = email;}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public List<Role> getRoles() {
return roles;
}
public List<Document> getUsersDocuments() {
return usersDocuments;
}
public void setUsersDocuments(List<Document> usersDocuments) {
this.usersDocuments = usersDocuments;
}
public List<Document> getSharedDocuments() {
return sharedDocuments;
}
public void setSharedDocuments(List<Document> sharedDocuments) {
this.sharedDocuments = sharedDocuments;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return getId() == user.getId();
}
#Override
public int hashCode() {
return Objects.hash(getId());
}
#Override
public String toString() {
return "User{" +
"firstName='" + firstName + '\'' +
", surname='" + surname + '\'' +
", email='" + email + '\'' +
", roles=" + roles +
'}';
}
}
My Document class:
#Entity
public class Document {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(unique = true)
private String name;
private String title;
private String description;
#Column(name = "resource_path")
private String resourcePath;
#Column(name = "upload_datetime", columnDefinition = "DATETIME")
#Temporal(TemporalType.TIMESTAMP)
private Date uploadDatetime;
#ManyToMany(mappedBy = "usersDocuments")
private List<User> documentsForUsers;
#ManyToOne
#JoinColumn(name="user_id", nullable=false)
private User user;
public Document() {
}
public Document(String title, String description){
this.title = title;
this.description = description;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getResourcePath() {
return resourcePath;
}
public void setResourcePath(String resourcePath) {
this.resourcePath = resourcePath;
}
#Override
public String toString() {
return "Document{" +
"id=" + id +
", title='" + title + '\'' +
", description='" + description + '\'' +
", resourcePath='" + resourcePath + '\'' +
", uploadDatetime=" + uploadDatetime + '\'' +
". user=" + user;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Document)) return false;
Document document = (Document) o;
return getId() == document.getId();
}
#Override
public int hashCode() {
return Objects.hash(getId());
}
public Date getUploadDatetime() {
return uploadDatetime;
}
public void setUploadDatetime(Date uploadDatetime) {
// Date startDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(uploadDatetime.toString());
this.uploadDatetime = uploadDatetime;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<User> getDocumentsForUsers() {
return documentsForUsers;
}
public void setDocumentsForUsers(List<User> documentsForUsers) {
this.documentsForUsers = documentsForUsers;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Perform this:
Optional<User> user = userService.getUserByEmail(createdBy);
Document document = new Document(title, desc);
document.setUploadDatetime(new Date());
document.setUser(user.get());
List<User> users = userService.getUsersByRoles(roles);
document.setDocumentsForUsers(users);
saveDocument(document);
#Override
public void saveDocument(Document document) {
entityManager.persist(document);
}
I think you need add the option to your #ManyToMany annotation: CascadeType.PERSIST.
By default, hibernate doesn't persists your relationship objects.
Try to use:
#ManyToMany(cascade = CascadeType.PERSIST)
Your class User is an Owner of relation #ManyToMany on
List<Document> usersDocuments;
as User has #JoinTable. Document class is an Inverse end.
If a Document is persisted then a data will be saved without relations. Because Inverse end cares only about itself but no relations.
By default you can persist a relation only from the owner side.
To be able to persist a relation from the inverse end then in your case as I tested:
In Document add cascade:
#ManyToMany(cascade = CascadeType.PERSIST, mappedBy = "usersDocuments")
private List<User> documentsForUsers;
and add a new code in your setter:
public void setDocumentsForUsers(List<User> documentsForUsers) {
if (documentsForUsers != null){
documentsForUsers.forEach(u -> {
u.getUsersDocuments().add(this); //here you should have not-null list u.getUsersDocuments()
});
}
this.documentsForUsers = documentsForUsers;
}
In User class add cascade:
#ManyToMany(cascade = CascadeType.PERSIST)
and
private List<Document> usersDocuments = new ArrayList<>();

Hibernate mappedBy and ManyToMany

I'm starting from scratch a new project and i got this problem which i cannot solve. I have three entities, and they all have a manytomany relationship with each other. There is the Cluster:
#Entity
#Component
#Table(name = "clusterEntity")
public class Cluster {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, updatable = false)
private Long id;
#Column(name = "name")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#ManyToMany
#JoinTable(name="cluster_user",
joinColumns=#JoinColumn(name="cluster_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="user_id", referencedColumnName="id"))
private List<User> users_cluster;
#ManyToMany
#JoinTable(name="cluster_sito",
joinColumns=#JoinColumn(name="cluster_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="sito_id", referencedColumnName="id"))
private List<Sito> sitos;
#Override
public String toString() {
return "Cluster{" +
"id=" + id +
", name='" + name +
", users='" + users_cluster.toString() +
'}';
}
}
This is the User:
#Entity
#Component
#Table(name = "userEntity")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, updatable = false)
private Long id;
#Column(name = "email", nullable = false, unique = true)
private String email;
#Column(name = "password_hash", nullable = false)
private String passwordHash;
#Column(name = "role", nullable = false)
#Enumerated(EnumType.STRING)
private Role role;
#Column(name = "G1", nullable = true)
private String G1;
#Column(name = "G2", nullable = true)
private String G2;
#Column(name = "G3", nullable = true)
private String G3;
#Column(name = "G4", nullable = true)
private String G4;
#Column(name = "G5", nullable = true)
private String G5;
#Column(name = "G6", nullable = true)
private String G6;
#Column (name = "access_token", nullable = true)
private String access_token;
#Column (name = "refresh_token", nullable = true)
private String refresh_token;
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public String getG1() {
return G1;
}
public void setG1(String g1) {
G1 = g1;
}
public String getG2() {
return G2;
}
public void setG2(String g2) {
G2 = g2;
}
public String getG3() {
return G3;
}
public void setG3(String g3) {
G3 = g3;
}
public String getG4() {
return G4;
}
public void setG4(String g4) {
G4 = g4;
}
public String getG5() {
return G5;
}
public void setG5(String g5) {
G5 = g5;
}
public String getG6() {
return G6;
}
public void setG6(String g6) {
G6 = g6;
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getRefresh_token() {
return refresh_token;
}
public void setRefresh_token(String refresh_token) {
this.refresh_token = refresh_token;
}
#ManyToMany(mappedBy="users_cluster")
private List<User> users_cluster;
#ManyToMany(mappedBy="users_sito")
private List<User> users_sito;
public User(){}
#Override
public String toString() {
return "User{" +
"id=" + id +
", email='" + email.replaceFirst("#.*", "#***") +
", passwordHash='" + passwordHash.substring(0, 10) +
", role=" + role +
'}';
}
}
This is the Sito:
#Entity
#Component
#Table(name = "sitoEntity")
public class Sito {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false, updatable = false)
private Long id;
#Column(name = "name")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#ManyToMany
#JoinTable(name="sito_user",
joinColumns=#JoinColumn(name="sito_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="user_id", referencedColumnName="id"))
private List<User> users_sito;
#Override
public String toString() {
return "Sito{" +
"id=" + id +
", name='" + name+
", users='" + users_sito.toString()+
'}';
}
}
When i try compiling with maven i get the following error about mappedBY, as if it was written on both side of the relation, but in fact it is written only on one side:
Caused by: org.hibernate.AnnotationException: Illegal use of mappedBy on both sides of the relationship: User.users_cluster
Anyone has any ideaof what am i doing wrong?
Clustor
As far as I can see the Cluster entity is annotated correctly except some kine of naming convention. Instead of
private List<User> users_cluster;
I would recommend using
private List<User> users;
The list contains users so it should be named to reflect that; good naming is the best documentation, (imo).
User
This entity seems to be correctly annotated but the references are wrong as they are self referencing. So the entity should be modified as follows if you want to create a many-to-many relationship between the thre entities:
public class User {
// ...
#ManyToMany(mappedBy="users")
private List<Cluster> clusters;
#ManyToMany(mappedBy="users")
private List<Sito> sitos;
// getters + setters
}
Sito
Here too I made a small modification as follows:
public class Sito {
// ...
#ManyToMany
#JoinTable(name="sito_user",
joinColumns=#JoinColumn(name="sito_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="user_id", referencedColumnName="id"))
private List<User> users;
#ManyToMany(mappedBy = "sitos")
private List<Cluster> clusters;
// getters + setters
}
Now your three entities should be related to each other as you desired.

How to make a join on Java with criteria builder

I have a database in which I need to make a Join from Java with a CriteriaBuilder.
I have this code so far:
CriteriaBuilder cb = entman.getCriteriaBuilder();
CriteriaQuery<Company> query = cb.createQuery(Company.class);
Root<Employee> teacher = query.from(Employee.class);
Join<Employee, Company> employees = teacher.join("id");
query.select(employees).where(cb.equal(teacher.get("name"), ""));
List<Company> results = entman.createQuery(query).getResultList();
return results;
After I run this code ( with springboot) i get this error: Cannot join to attribute of basic type
Does anyone know what should I do to make it work ?
PS: I will provide any other information if needed.
Thanks in advance.
company database
employee database
L.E.:
Employee:
#Entity
public class Employee {
#Id
#GeneratedValue
private Long id;
#Column(nullable = false)
#Size(min = 1)
private String name;
#Column(nullable = false)
#Temporal(TemporalType.DATE)
private Date hire_date;
#ManyToOne
//#JoinColumn(name = "id")
private Company company;
public Employee() {}
public Employee(Long id, String name, Date date, Company company) {
setId(id);
setName(name);
setHire_date(date);
setCompany(company);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getHire_date() {
return hire_date;
}
public void setHire_date(Date hire_date) {
this.hire_date = hire_date;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
Company:
#Entity
public class Company {
#Id
#GeneratedValue
private Long id;
#Column(nullable = false)
#Size(min = 1)
private String name;
#OneToMany(mappedBy="company", cascade = CascadeType.ALL, fetch=FetchType.EAGER, orphanRemoval=true)
private Collection<Employee> employees;
public Company() {}
public Company(Long id, String name) {
setId(id);
setName(name);
}
public Company(Long id, String name, Collection<Employee> employees) {
setId(id);
setName(name);
setEmployees(employees);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection<Employee> getEmployees()
{
return employees;
}
public void setEmployees(Collection<Employee> employees) {
this.employees = employees;
}
#Override
public String toString() {
return "Company [id=" + id + ", name=" + name + ", employees=" + employees.toString() + "]";
}
}
You need to have a Teacher element, not a reference to id because you cannot join a #Column field...
Change id mapping from #Column:
#Column(name = "id")
private Integer id;
with a #ManyToOne (or the needed one) association:
#ManyToOne
#JoinColumn(name = "id")
private Teacher teacher;
After this your join will work as expected.

issue with Criteria when making an association on 2 tables with a fereign key

I m trying to learn about hibernate and Criteria.
i have 2 tables RATS and SICKNESS.
I set a foreign key in RATS : RATS.Sickness_Id = SICKNESS.ID.
I m trying to get with Criteria an equivalent of SQL:
select * from RATS r, SICKNESS s where s.id = r.sickness_id
I assumed it was this association:
session
.createCriteria(Rats.class)
.createCriteria(Sickness.class)
.toList()
This unfortunately ends up with:
org.hibernate.QueryException: could not resolve property: entities of: entities.Rats
Strange part is that both:
session.createCriteria(Rats.class).toList()
and
session.createCriteria(Sickness.class).toList()
work fine....
I'm a bit puzzled.
Here are my entities classes code:
#Entity
#Table(name = "RATS")
public class Rats implements java.io.Serializable {
private int id;
private Sickness sickness;
private String name;
private int age;
public Rats() {
}
public Rats(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Rats(int id, Sickness sickness, String name, int age) {
this.id = id;
this.sickness = sickness;
this.name = name;
this.age = age;
}
#Id
#Column(name = "ID", unique = true, nullable = false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "Sickness_Id")
public Sickness getSickness() {
return this.sickness;
}
public void setSickness(Sickness sickness) {
this.sickness = sickness;
}
#Column(name = "Name", nullable = false, length = 50)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "Age", nullable = false)
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
String returnString = "My name is " + getName() + ", I am " + getAge()+ ". ";
returnString += getSickness() == null ? "I am healthy like hell! :)" : "I suffer from " + getSickness().getNom();
return returnString;
}
}
and
#Entity
#Table(name = "SICKNESS")
public class Sickness implements java.io.Serializable {
private int id;
private String nom;
private Set<Rats> ratses = new HashSet<Rats>(0);
public Sickness() {
}
public Sickness(int id) {
this.id = id;
}
public Sickness(int id, String nom, Set<Rats> ratses) {
this.id = id;
this.nom = nom;
this.ratses = ratses;
}
#Id
#Column(name = "Id", unique = true, nullable = false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
#Column(name = "Nom", length = 50)
public String getNom() {
return this.nom;
}
public void setNom(String nom) {
this.nom = nom;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "sickness")
public Set<Rats> getRatses() {
return this.ratses;
}
public void setRatses(Set<Rats> ratses) {
this.ratses = ratses;
}
#Override
public String toString() {
return getNom()
+ ( getRatses() != null ? (", getRatses()=" + getRatses() + "]"): "" );
}
}
What did I miss?
Thanks in advance.
On Rats entity, the Sickness entity property is:
private Sickness sickness;
Accordingly, your association must use the same name.
session.createCriteria(Rats.class)
.createCriteria("sickness")
.list();
One other solution, should be to change Rats to use EAGER Fetch:
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "Sickness_Id")
public Sickness getSickness() {
return this.sickness;
}
public void setSickness(Sickness sickness) {
this.sickness = sickness;
}
and then use:
session.createCriteria(Rats.class)
.list();

Categories