Hibernate从onetomany检索列表

时间:2010-09-08 11:33:21

标签: java hibernate orm hql

我管理(正如你在我发表的老帖子中看到的那样)通过hibernate插入一个onetomany关系。我的两个实体类如下所示:

Project.java:

@Entity
public class Project {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private int id; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy="project")
    @OrderColumn(name = "project_index")
    List<Application> applications;
....

Application.java(项目的子项。一个项目可以有多个应用程序,但一个应用程序只属于一个项目)

@Entity
public class Application {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private int id;
    @ManyToOne
    @JoinColumn(name = "project_id")
    private Project project;
...

到目前为止,数据的插入效果很好。但是从我的数据库中获取数据是个问题。我试过两种方法:


方式1:我检索项目并尝试从列表属性中取出应用程序。但不幸的是,应用程序实体处于'storedSnapshot'中,这对我来说似乎很不对。这是我的调试屏幕截图:

alt text

实际上这种方式有效!我在其他地方犯了一些错误......


方式2:我尝试通过sql查询检索所有应用程序的列表:

public List<Application> getApplications(int project_id) {
  Session session = HibernateUtil.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  List<Application> applications = session.createQuery("from Application a where a.project_id=" + project_id + " ").list();
  return applications;
 }

..引发奇怪的异常-.-

org.hibernate.QueryException:无法解析属性:project_id:de..common.entities.Application [from de..common.entities.Application a where a.project_id=1 ]

方法2的问题在于我混淆了SQL和HQL。


hibernate初学者的一点帮助会很棒:-) 干杯..

3 个答案:

答案 0 :(得分:4)

您应该可以通过以下方式访问应用程序:

List<Application> applications = project.getApplications();

PersistentBag正在实施java.util.List,所以你不应该关心它的内部。

您只需要一个开放的会话即可,否则会抛出LazyInitializationException

答案 1 :(得分:2)

  

我尝试通过sql query(...)检索所有应用程序的列表,这会引发奇怪的异常

异常并不奇怪,它正好告诉你错误:Application没有任何project_id属性,这是真的(project_id是数据库列)。 / p>

您的查询不是 SQL 查询,而是 JPQL 查询。 JPQL查询是针对实体(对象)及其关联执行的。所以你需要思考对象和关联。

在您的情况下,(假设您还没有Project个实例但只有项目id),您可以执行以下操作:

Query q = session.createQuery("FROM Application a WHERE a.project.id = :id");
q.setParameter("id", project_id);
List<Application> applications = (List<Application>) q.list();

答案 2 :(得分:1)

方式1:我不知道StoredSnapshot,但尝试将应用程序列表的FetchType设置为“EAGER”。也许这会解决它。

方式2:您正在对数据模型创建查询,而不是在数据库上创建查询。因此字段应该是java映射中的字段。在这种情况下:

List applications = session.createQuery("from Application a where a.project=" + project).list();

请注意,传递给函数的参数应为Project类型,而不是int类型。

此外,通过使用命名查询,您可以执行此操作:

 @NamedQuery(name="projectById",
             query="SELECT p FROM Project p"
                  + " LEFT JOIN FETCH applications"
            )