Spring Hibernate 一对多关系

发布于 2024-12-23 18:48:18 字数 4897 浏览 0 评论 0原文

我正在做一些 Spring + Hibernate 练习。作为示例项目,我选择了一个博客。我有两个模型;博客对象和标签对象。他们有一对多的关系。当我在服务器上发布和运行时,我可以在数据库上看到博客项目,但休眠不会插入标签项目。我无法弄清楚我在这里缺少什么:

在此处输入图像描述

博客模型中的标签

@OneToMany(targetEntity=Tags.class, mappedBy="blog", fetch=FetchType.EAGER)
    @Column(name="blog_tags")
    public List<Tags> getBlogTags() {
        return blogTags;
    }

    public void setBlogTags(List<Tags> blogTags) {
        this.blogTags = blogTags;
    }

标签模型中的博客:

@ManyToOne(targetEntity=Blog.class,fetch=FetchType.EAGER)
@JoinColumn(name="blog_id")
public Blog getBlog() {
    return blog;
}

public void setBlog(Blog blog) {
    this.blog = blog;
}

hibernate.hbm.xml:

<!-- Hibernate session factory -->
<bean id="sessionFactory" 
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

    <property name="dataSource">
      <ref bean="dataSource"/>
    </property>

    <property name="hibernateProperties">
       <props>
         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
         <prop key="hibernate.show_sql">true</prop>
       </props>
    </property>

    <property name="annotatedClasses">
    <list>
        <value>com.udb.blog.model.Blog</value>
        <value>com.udb.blog.model.Tags</value>
    </list>
    </property>

    </bean>
</beans>

blogBo(使用与 blogDao 相同的实现):

public interface BlogBo {

    void save(Blog blog);
    void update(Blog blog);
    void delete(Blog blog);
    Blog getByTitle(String str);

}

测试 Servlet:

    ApplicationContext appContext = new ClassPathXmlApplicationContext("spring/config/BeanLocations.xml");
    BlogBo blogBo = (BlogBo) appContext.getBean("blogBo");




    Blog blog = new Blog();
    blog.setBlogTitle("My Second blog");
    blog.setBlogDescription("testing onetomany relationship");
    blog.setBlogBody("testing done!");
    blog.setBlogDate(new Date(0));

    Tags tag = new Tags();
    tag.setTagName("first blog");

    Tags tag2 = new Tags();
    tag2.setTagName("Spring");

    tag.setBlog(blog);
    tag2.setBlog(blog);

    blogBo.save(blog);

    Blog blog2 = blogBo.getByTitle("My Second blog");
    response.getWriter().write(blog2.toString());

hibernate 输出:

Hibernate: insert into burak1_udb.blog (blog_body, blog_date, blog_desc, blog_title) values (?, ?, ?, ?)
Hibernate: select blog0_.blog_id as blog1_0_, blog0_.blog_body as blog2_0_, blog0_.blog_date as blog3_0_, blog0_.blog_desc as blog4_0_, blog0_.blog_title as blog5_0_ from burak1_udb.blog blog0_ where blog_title=?
Hibernate: select blogtags0_.blog_id as blog3_1_, blogtags0_.tag_id as tag1_1_, blogtags0_.tag_id as tag1_1_0_, blogtags0_.blog_id as blog3_1_0_, blogtags0_.tag_name as tag2_1_0_ from burak1_udb.tags blogtags0_ where blogtags0_.blog_id=?
Hibernate: select blogtags0_.blog_id as blog3_1_, blogtags0_.tag_id as tag1_1_, blogtags0_.tag_id as tag1_1_0_, blogtags0_.blog_id as blog3_1_0_, blogtags0_.tag_name as tag2_1_0_ from burak1_udb.tags blogtags0_ where blogtags0_.blog_id=?

我我认为我需要更改 blogBo 逻辑,即构造函数可以有一个标签列表,但这样我就不需要一个注释,并且如果我想使用此注释,我想了解我缺少什么。

编辑: 我的临时解决方案是我已经更改为manytomany。创建第三个表 blogtags 后:

**@Entity
@Table(name="blog_tags")
public class BlogTags implements Serializable{
    /**
     * 
     */
    public BlogTags(Blog blog, Tags tag){

        this.blogId = blog.getBlogId();
        this.tagId = tag.getTagId();
    }**

然后我将 blogDao 更改如下:

public void save(Blog blog, List<Tags> tags) {
    getHibernateTemplate().save(blog);

    for(Tags tag:tags){
        getHibernateTemplate().saveOrUpdate(tag);
        BlogTags blogtags = new BlogTags(blog, tag);
        getHibernateTemplate().saveOrUpdate(blogtags);

    }

和最终的 servlet:

Tags tag = new Tags();
        tag.setTagName("myTag");

        Tags tag2 = new Tags();
        tag2.setTagName("Spring");

        Tags tag3 = new Tags();
        tag3.setTagName("Hibernate");

        Tags tag4 = new Tags();
        tag4.setTagName("ManytoMany");

        List<Tags> tags = new ArrayList<Tags>();
        tags.add(tag);
        tags.add(tag2);
        tags.add(tag3);
        tags.add(tag4);

        Blog blog = new Blog();
        blog.setBlogTitle("myTest");
        blog.setBlogDescription("testDesc");
        blog.setBlogBody("body");
        blog.setBlogDate(new Date(0));

        blogBo.save(blog, tags);

I am doing some Spring + Hibernate exercise. As an example project I have chosen a Blog. I have two model; Blog object and Tags Object. They have onetomany relationship. When I publish and run on server I can see blog items on database but hibernate not inserting tag items. I couldnt figure out what I am missing here:

enter image description here

tags in Blog model:

@OneToMany(targetEntity=Tags.class, mappedBy="blog", fetch=FetchType.EAGER)
    @Column(name="blog_tags")
    public List<Tags> getBlogTags() {
        return blogTags;
    }

    public void setBlogTags(List<Tags> blogTags) {
        this.blogTags = blogTags;
    }

blog in Tags model:

@ManyToOne(targetEntity=Blog.class,fetch=FetchType.EAGER)
@JoinColumn(name="blog_id")
public Blog getBlog() {
    return blog;
}

public void setBlog(Blog blog) {
    this.blog = blog;
}

hibernate.hbm.xml:

<!-- Hibernate session factory -->
<bean id="sessionFactory" 
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

    <property name="dataSource">
      <ref bean="dataSource"/>
    </property>

    <property name="hibernateProperties">
       <props>
         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
         <prop key="hibernate.show_sql">true</prop>
       </props>
    </property>

    <property name="annotatedClasses">
    <list>
        <value>com.udb.blog.model.Blog</value>
        <value>com.udb.blog.model.Tags</value>
    </list>
    </property>

    </bean>
</beans>

blogBo (using same implementation as blogDao):

public interface BlogBo {

    void save(Blog blog);
    void update(Blog blog);
    void delete(Blog blog);
    Blog getByTitle(String str);

}

test Servlet:

    ApplicationContext appContext = new ClassPathXmlApplicationContext("spring/config/BeanLocations.xml");
    BlogBo blogBo = (BlogBo) appContext.getBean("blogBo");




    Blog blog = new Blog();
    blog.setBlogTitle("My Second blog");
    blog.setBlogDescription("testing onetomany relationship");
    blog.setBlogBody("testing done!");
    blog.setBlogDate(new Date(0));

    Tags tag = new Tags();
    tag.setTagName("first blog");

    Tags tag2 = new Tags();
    tag2.setTagName("Spring");

    tag.setBlog(blog);
    tag2.setBlog(blog);

    blogBo.save(blog);

    Blog blog2 = blogBo.getByTitle("My Second blog");
    response.getWriter().write(blog2.toString());

hibernate output:

Hibernate: insert into burak1_udb.blog (blog_body, blog_date, blog_desc, blog_title) values (?, ?, ?, ?)
Hibernate: select blog0_.blog_id as blog1_0_, blog0_.blog_body as blog2_0_, blog0_.blog_date as blog3_0_, blog0_.blog_desc as blog4_0_, blog0_.blog_title as blog5_0_ from burak1_udb.blog blog0_ where blog_title=?
Hibernate: select blogtags0_.blog_id as blog3_1_, blogtags0_.tag_id as tag1_1_, blogtags0_.tag_id as tag1_1_0_, blogtags0_.blog_id as blog3_1_0_, blogtags0_.tag_name as tag2_1_0_ from burak1_udb.tags blogtags0_ where blogtags0_.blog_id=?
Hibernate: select blogtags0_.blog_id as blog3_1_, blogtags0_.tag_id as tag1_1_, blogtags0_.tag_id as tag1_1_0_, blogtags0_.blog_id as blog3_1_0_, blogtags0_.tag_name as tag2_1_0_ from burak1_udb.tags blogtags0_ where blogtags0_.blog_id=?

I think I need to change blogBo logic that constructor can have a list of tags but then I will not need onetomany annotation andI want to understand what I is missing if I want to use this annotation.

EDIT:
My temporary solution is I have changeg to manytomany. After I have created a third table, blogtags:

**@Entity
@Table(name="blog_tags")
public class BlogTags implements Serializable{
    /**
     * 
     */
    public BlogTags(Blog blog, Tags tag){

        this.blogId = blog.getBlogId();
        this.tagId = tag.getTagId();
    }**

Then I have changed blogDao as below:

public void save(Blog blog, List<Tags> tags) {
    getHibernateTemplate().save(blog);

    for(Tags tag:tags){
        getHibernateTemplate().saveOrUpdate(tag);
        BlogTags blogtags = new BlogTags(blog, tag);
        getHibernateTemplate().saveOrUpdate(blogtags);

    }

And final servlet:

Tags tag = new Tags();
        tag.setTagName("myTag");

        Tags tag2 = new Tags();
        tag2.setTagName("Spring");

        Tags tag3 = new Tags();
        tag3.setTagName("Hibernate");

        Tags tag4 = new Tags();
        tag4.setTagName("ManytoMany");

        List<Tags> tags = new ArrayList<Tags>();
        tags.add(tag);
        tags.add(tag2);
        tags.add(tag3);
        tags.add(tag4);

        Blog blog = new Blog();
        blog.setBlogTitle("myTest");
        blog.setBlogDescription("testDesc");
        blog.setBlogBody("body");
        blog.setBlogDate(new Date(0));

        blogBo.save(blog, tags);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝眼睛不忧郁 2024-12-30 18:48:18

尝试手动将标签添加到您的博客,这样就

tag.setBlog(blog);
tag2.setBlog(blog);

可以:

blog.getBlogTags().add(tag);
blog.getBlogTags().add(tag2);

Try to manually add Tag to your Blog, so that instead of:

tag.setBlog(blog);
tag2.setBlog(blog);

do:

blog.getBlogTags().add(tag);
blog.getBlogTags().add(tag2);
青衫负雪 2024-12-30 18:48:18

@OneToMany 关系端,即在 Blog 实体端,将级联样式设置为 CascadeType.SAVE_UPDATE 以获取与其关联的保存或更新操作级联子实体。否则您必须手动保存它们。

On @OneToMany relation side i.e on Blog entity side set cascade style to CascadeType.SAVE_UPDATE to get the save or update operation get cascade to it's associated child entities. Otherwise you have to save them manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文