我正在使用带有Spring,Hibernate,JPA和MySQL的Java8。
我有以下表格:
+----------+ +-----------------+ +-----------+
| PERSON | | RATING_PERSON | | RATING |
+----------+ +-----------------+ +-----------+
| ID | | PER_ID | | ID |
| | | RAT_ID | | |
+----------+ +-----------------+ +-----------+
然后执行以下代码:
@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;
}
但是得到以下错误:
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.
当我在MySQLWorkbench中运行完全相同的SQL语句时,它会毫无问题地执行。
SELECT * FROM ebdb.rating as r WHERE r.ID = (SELECT rp.RAT_ID from ebdb.rating_person as rp where rp.PER_ID = 385)
问题
有人可以建议我如何让Hibernate Native Query执行这个SQL吗?
由于
更新
我尝试删除Rating.class
,即更改:
Query q = entityManager.createNativeQuery(sb.toString(), Rating.class);
为:
Query q = entityManager.createNativeQuery(sb.toString());
这部分解决了这个问题。
我得到了一个结果集:
List<Rating> ratings = (List<Rating>) q.getResultList();
ratings
的价值:
[[Ljava.lang.Object;@5b5c9618]
但是,当我尝试使用ratings
:
for (Rating rating : ratings) {
...
}
我收到以下错误:
[Ljava.lang.Object; cannot be cast to com.jobs.spring.domain.Rating
更多信息:
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;
}
}
答案 0 :(得分:1)
I am not sure why the native query doesn't work, but I solved this issue by using a hibernate query:
@Override
public List<Rating> findByRatedBy(Person person) {
final EntityManagerFactory entityManagerFactory = entityManager.getEntityManagerFactory();
final CriteriaBuilder criteriaBuilder = entityManagerFactory.getCriteriaBuilder();
CriteriaQuery<Rating> criteria = criteriaBuilder.createQuery(Rating.class);
Root<Rating> root = criteria.from(Rating.class);
ParameterExpression<Job> paramJob = criteriaBuilder.parameter(Job.class);
ParameterExpression<Person> paramPerson = criteriaBuilder.parameter(Person.class);
criteria.select(root).where(
criteriaBuilder.equal(root.get("person"), paramPerson)
);
List<Order> orderList = new <Order>ArrayList();
orderList.add(criteriaBuilder.desc(root.get("reviewDate")));
criteria.orderBy(orderList);
TypedQuery<Rating> queryRating = entityManager.createQuery(criteria);
queryRating.setParameter(paramPerson, person);
List<Rating> results = null;
results = queryRating.getResultList();
return results;
}