Hibernate本机查询错误:找不到列

时间:2017-07-12 07:13:08

标签: java mysql sql hibernate jpa

我正在使用带有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]

enter image description here

但是,当我尝试使用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;
    }
}

1 个答案:

答案 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;
}