如何使用休眠模式查询具有嵌套对象的嵌套对象,该嵌套对象具有嵌套的对象集合 [英] How to use hibernate to query for an object with a nested object that has a nested collection of objects

查看:50
本文介绍了如何使用休眠模式查询具有嵌套对象的嵌套对象,该嵌套对象具有嵌套的对象集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Hibernate,我需要在MySQL数据库中查询与Poll实体具有一对一关系的Post实体,而该Poll实体与Answer实体具有一对多的关系.我需要Post对象包含Poll对象,而其Poll对象包含Answer对象.这是基本的类设置:

Using Hibernate, I need to query a MySQL database for a Post entity that has a one-to-one relationship with a Poll entity that has a one-to-many relationship with an Answer entity. I need the Post object to contain the Poll object and its Poll object to contain its Answer objects. Here's the basic class setup:

更新: Post表必须没有主键列.这是浪费数据.我需要能够使用user_id列从数据库中获取Post对象.使用user_id列获取Post对象是完成此操作的唯一方法,因此,对于我来说,拥有主键列是没有意义的.因此,如果您要提供一个答案,以深入了解解决 问题的解决方案,请牢记这些规格.

Update: The Post table must not have a primary key column. It is a waste of data. I need to be able to get Post objects from the database using the user_id column. Getting Post objects using the user_id column is the only way it will ever be done, so it makes no sense for me to have a primary key column. So if you're going to provide an answer that provides insight into a solution that solves my problem, please keep those specifications in mind.

邮政课:

@Entity
@Table(name="user_feed")
public class Post implements Serializable {
    //id for the user that is meant to receive the post
    //*post object is taken from a table that will contain
    //*posts for many different users
    @Id
    @Column(name="user_id")
    private long mUserId;

    //poll id
    @Id
    @Column(name="poll_id")
    private long mPollId;

    //boolean that indicates whether this post is a repost
    @Column(name="is_repost")
    private boolean mIsRepost;

    //date the post was created
    @Column(name="date_created")
    private Date mDateCreated;

    //the poll this post contains
    @OneToOne
    @JoinColumn(name="poll_id")
    private Poll mPoll;

投票类别:

@Entity
@Table(name="poll")
public class Poll implements Serializable{

    //the poll's id
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long mId;

    //id of the user who created the poll
    @Column(name="user_id")
    private long mUserId;

    //the text of the poll's question
    @Column(name="question")
    private String mQuestion;

    //the date the poll was created
    @Column(name="date_created")
    private Date mDateCreated;

    //the answer objects for this poll
    @OneToMany
    @JoinColumn(name="id")
    private List<Answer> mAnswers;

答案课:

@Entity
@Table(name="answer")
public class Answer implements Serializable {

    //id for a particular answer
    //*this is not a necessary value for the application logic, but
    //*Hibernate forces me to designate an @Id annotation for every
    //*entity, so I created this field and the associated column in
    //*the database
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long mId;

    //the answer's text
    @Column(name="answer_text")
    private String mAnswer;

    //the id of the poll to which this answer pertains to
    @Column(name="poll_id")
    private long mPollId;

***我对此表的ID感到困惑.每个答案都有一个主键是没有意义的,但是Hibernate在类中需要某种@Id注释,因此我决定为了Hibernate在表中创建一个主键列.它从未使用过.我想摆脱它,但是除了当前的文本外,实际上没有什么可以使一个Answer对于同一民意测验在另一个答案中独树一帜–应用逻辑不是必需的.

***I'm confused about the id for this table. It doesn't make sense for each answer to have a primary key, but Hibernate requires some sort of @Id annotation in the class, so I decided to just create a primary key column in the table for the sake of Hibernate. It's never used. I would like to get rid of it, but there really isn't anything that makes one Answer unique from another for the same poll except for their text at the moment -- it's not necessary for the application logic.

我想出的查询:不起作用

Query I came up with: doesn't work .

这个查询实际上只是我的测试,以查看是否可以获取一个带有所有嵌套对象的Post对象.我知道我能不能得到一个,一个收藏就不会花太多时间了,但是我什至无法得到一个.

This query was really just me testing to see if I could get a single Post object with all of its nested objects. I knew if I could get one, getting a collection wouldn't be much more of a stretch -- but I can't even get one.

Session session = HibernateUtilities.openSession();
        session.beginTransaction();

        //29 is a post meant for a particular user and 47 is the id of the    
        //poll that should be contained in the post
        Post post = (Post)session.get(Post.class, new Post(29, 47));

        session.getTransaction().commit();
        session.close();

        //suppose to return the post in JSON format to a client, but it
        //doesn't work when I create the one-to-many relationship between       
        //the poll and it's answers. It only works without the relationship;   
        //which I've defined in the Poll class
        return mGson.toJson(post);

推荐答案

我自己解决了这个问题.以下代码中的所有注释都指定了我对问题中提出的代码所做的更改,并解释了为什么要进行更改.

Solved it myself. All the comments in the below code designate the changes I made to the code I presented in the question and explain why I made them.

邮政课:

@Entity
@Table(name="user_feed")
public class Post implements Serializable {
    @Id
    @Column(name="user_id")
    private long mUserId;

    //removed long mPollId
    //hibernate is capable of getting the foreign key for a post's
    //poll_id column from its poll object -- mPoll
    //so i don't have to have a separate field for the id of this post's
    //poll

    @Column(name="is_repost")
    private boolean mIsRepost;

    @Column(name="date_created")
    private Date mDateCreated;

    //made this field part of the composite id instead of long mPollId
    //pretty much the same composite key as before just had to alter
    //my implementation of Post.equals(Object) to use this poll's id
    //instead of this class's mPollId field
    //implementing your own .equals(Object) method is necessary when
    //creating composite keys as i do with multiple @Id annotations
    //i think you also have to implement your own .hashCode() method too
    //but the word hash scares me, so I didn't do it
    //the code works, so i'm just gonna let it rock
    @OneToOne
    @JoinColumn(name="poll_id")
    private Poll mPoll;

投票类别:

@Entity
@Table(name="poll")
public class Poll implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long mId;

    @Column(name="user_id")
    private long mUserId;

    @Column(name="question")
    private String mQuestion;

    @Column(name="date_created")
    private Date mDateCreated;

    //removed @JoinColumn -- not completely sure about why it wasn't
    //helping, but many of the examples similar to my use case didn't
    //use it so I got rid of it
    //added mappedBy variable -- still not really sure what it does
    //but it works
    //and added FetchType.EAGER so everytime a Poll object is loaded
    //the answers it's associated with are loaded too
    @OneToMany(mappedBy="mPoll", fetch=FetchType.EAGER)
    @Cascade({CascadeType.SAVE_UPDATE, CascadeType.REMOVE})
    private List<Answer> mAnswers;

答案课:

@Entity
@Table(name="answer")
public class Answer implements Serializable {

    //turns out having a primary key on the answer table is actually useful
    //for the application logic. would you look at that
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private long mId;

    @Column(name="answer_text")
    private String mAnswer;

    //got rid of long mPollId
    //it was for the same reason i did in the Post class
    //hibernate does the work for me with the mPoll object and the
    //annotations i've provided on it

    //made the relationship between a poll and its answers bidirectional
    //not entirely sure how adding the below annotations to the new
    //Poll field fixed my problems, but it did
    //i imagine it somehow tells hibernate that the primary key
    //for the below object is the foreign key represented by poll_id in the
    //database table for this entity
    //and making insertable=true enables hibernate to insert that foreign
    //key into the appropriate column in the database when this entity
    //is saved
    //updatable seemed to be necessary
    //hibernate complained when it wasn't there
    //and nullable was in the helpful examples i found so it was copy and
    //pasted along with the rest of the helpful stuff here
    //this field can't be nullable anyways so semantically, it makes sense
    //for it to be there
    @ManyToOne
    @JoinColumn(name="poll_id", nullable = false, insertable=true, updatable=false)
    private Poll mPoll;

最终功能查询:确实有效

Final functioning query: does work

Session session = HibernateUtilities.openSession();
        session.beginTransaction();


        List<Post> usersFeed = session.createQuery("select p from Post p where p.mUserId = :userId")
                  .setString("userId", userId)
                  .list();


        session.getTransaction().commit();
        session.close();

这篇关于如何使用休眠模式查询具有嵌套对象的嵌套对象,该嵌套对象具有嵌套的对象集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆