I am using Java8 with Spring, Hibernate, JPA and MySQL.
I have the following tables:
+----------+ +-----------------+ +-----------+
| PERSON | | RATING_PERSON | | RATING |
+----------+ +-----------------+ +-----------+
| ID | | PER_ID | | ID |
| | | RAT_ID | | |
+----------+ +-----------------+ +-----------+
Then execute the following code:
@Override
public List<Rating> findByRatedBy(Long personId) {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT * FROM ebdb.rating as r ");
sb.append(" WHERE r.ID = (SELECT rp.RAT_ID ");
sb.append(" from ebdb.rating_person as rp where rp.PER_ID = :perId) ");
// sb.append(" SELECT r.* FROM ebdb.rating as r ");
// sb.append(" INNER JOIN ebdb.rating_person as rp ON r.ID = rp.RAT_ID ");
// sb.append(" WHERE rp.PER_ID = :perId ");
Query q = entityManager.createNativeQuery(sb.toString(), Rating.class);
q.setParameter("perId", personId);
List<Rating> ratings = (List<Rating>) q.getResultList();
return ratings;
}
But get the following error:
WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-7) SQL Error: 0, SQLState: S0022 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-7) Column 'PER_ID' not found.
When I run the exact same SQL statement in MySQLWorkbench, it executes with no problems.
SELECT * FROM ebdb.rating as r WHERE r.ID = (SELECT rp.RAT_ID from ebdb.rating_person as rp where rp.PER_ID = 385)
Question
Can anyone please advise how I can get the Hibernate Native Query to execute this SQL?
Thanks
UPDATE
I tried removing the Rating.class
, i.e. changing:
Query q = entityManager.createNativeQuery(sb.toString(), Rating.class);
to:
Query q = entityManager.createNativeQuery(sb.toString());
This partially solves the problem.
I do get a result set:
List<Rating> ratings = (List<Rating>) q.getResultList();
The value of ratings
:
[[Ljava.lang.Object;@5b5c9618]
However, when I try use the ratings
:
for (Rating rating : ratings) {
...
}
I get the following error:
[Ljava.lang.Object; cannot be cast to com.jobs.spring.domain.Rating
More Info:
Rating.java
@Entity
@Table(name="rating")
@XmlRootElement(name="rating")
public class Rating extends AbstractDomain<Long> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "STARS", nullable = false)
private Long rating;
@Size(min=0, max=500)
@Column(name = "REVIEW", nullable = false)
private String review;
@Column(name = "REVIEW_DATE", nullable = false)
private Long reviewDate;
@ManyToOne(fetch=FetchType.EAGER)
@JoinTable
(
name="rating_job",
joinColumns={ @JoinColumn(name="RAT_ID", referencedColumnName="ID") },
inverseJoinColumns={ @JoinColumn(name="JOB_ID", referencedColumnName="ID") }
)
private Job job;
@ManyToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable
(
name="rating_person",
joinColumns={ @JoinColumn(name="RAT_ID", referencedColumnName="ID") },
inverseJoinColumns={ @JoinColumn(name="PER_ID", referencedColumnName="ID") }
)
private Person person;
@Column(name = "ANONYMOUS", nullable = false)
private Integer anonymous;
@XmlElement
public Integer getAnonymous() {
return anonymous;
}
public void setAnonymous(Integer anonymous) {
this.anonymous = anonymous;
}
@XmlElement
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@XmlElement
public Long getRating() {
return rating;
}
public void setRating(Long rating) {
this.rating = rating;
}
@XmlElement
public String getReview() {
return review;
}
public void setReview(String review) {
this.review = review;
}
@XmlElement
public Long getReviewDate() {
return reviewDate;
}
public void setReviewDate(Long reviewDate) {
this.reviewDate = reviewDate;
}
@XmlElement
public Job getJob() {
return job;
}
public void setJob(Job job) {
this.job = job;
}
@XmlElement
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}