【问题标题】:Query for Many-To-Many relation using hibernate使用休眠查询多对多关系
【发布时间】:2012-07-06 22:58:21
【问题描述】:

我在使用休眠的资源类中有多对多关系。在 Category 类中:

@Entity
public class Category {

    Id
    @GeneratedValue
    private long id;

    @ManyToMany
    @JoinTable(name = "category_activity", 
    joinColumns = { @JoinColumn(name = "Category_id") }, 
    inverseJoinColumns = { @JoinColumn(name = "activities_id") })
    private Collection<Activity> activities;
}

在Activity类中:

@Entity
public class Activity {

    @Id
    @GeneratedValue
    private long id;

    @ManyToMany
    @JoinTable(name="category_activity", 
    joinColumns={@JoinColumn(name="activities_id")},
    inverseJoinColumns={@JoinColumn(name="Category_id")})
    private Collection<Category> category;
}

当我在它们之间建立 oneToMany 关系时,我使用的查询对我来说效果很好:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Collection<Activity> activities = (Collection<Activity>) session.createQuery("from Activity as a where a.category.id=" + categoryId + " order by a.key").list();
session.getTransaction().commit(); 

感谢任何帮助我解决多对多关系查询的问题?

我也使用了这个查询:

activities = (List<Activity>) session.createQuery("from Activity a join a.category cs where cs.id= :categoryId order by a.key").setLong("categoryId", categoryId).list();

我在堆栈跟踪中收到此错误:

<html><head><title>Apache Tomcat/7.0.23 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.Comparable
    java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
    java.util.ComparableTimSort.sort(Unknown Source)
    java.util.ComparableTimSort.sort(Unknown Source)
    java.util.Arrays.sort(Unknown Source)
    java.util.Collections.sort(Unknown Source)
    se.softwerk.timelog.controller.ActivityManager.activityList2(ActivityManager.java:64)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
    com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
    com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
    com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
    com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
</pre></p><p><b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/7.0.23 logs.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.23</h3></body></html>

【问题讨论】:

    标签: sql hibernate many-to-many


    【解决方案1】:

    首先,您不应该连接字符串,这为SQLInjection attacks 打开了大门,您应该使用命名参数。更多关于named parameters here

    第二,如果你有ManyToMany关系,双方应该是复数形式:

    这个

    private Collection<Category> category;
    

    应该是这样的:

    private Collection<Category> categories;
    

    现在关于你的特定问题,你有这个

    from Activity as a where a.category.id= :categoryId order by a.key
    

    你需要这个:

    from Activity a join a.category cs where cs.id= :categoryId  order by a.key
    

    【讨论】:

    • 谢谢你的回复,还是不行,这是堆栈跟踪中的错误:java.lang.ClassCastException: [Ljava.lang.Object;不能转换为 java.lang.Comparable
    • 那不是完整的stacktrace,其实看起来无关,请贴出完整的stacktrace
    • 谢谢,我把它加到了问题的最后。
    • 是的,我现在已经看到了...您是否意识到 JPA 和 Hibernate 包都没有出现在您的堆栈跟踪中? (这意味着堆栈跟踪与您的问题无关,您在其他地方遇到问题,显然在调用 Collections.sort 时方法 activityList2 的第 64 行的文件 ActivityManager.java 上)。您应该为此提出一个新的不同问题(并将其标记为已回答)...
    • 谢谢,我想我需要提到我有一个使用 Jersey 的 JAX-RS 项目。但是您提到的查询现在解决了一个新问题:stackoverflow.com/questions/11379017/…
    猜你喜欢
    • 2019-12-17
    • 2012-11-22
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多