【问题标题】:Hibernate : One-to-many bi-directional mapping storingHibernate:一对多的双向映射存储
【发布时间】:2017-06-20 17:33:04
【问题描述】:

我实际上是 hibernate 的新手,并且正在研究 一对多 双向映射。关系是这样的

  1. 一个用户拥有许多博客
  2. 一个用户拥有许多论坛

据我了解,如果我们在 Blog 模型中使用 @ManyToOne 注释和 @JoinColumn ,则不需要添加外键(用户 id) 列在博客中显式。但问题是,当我尝试持久化数据时,用户 id 列采用空值。如果我在博客模型中显式写入用户 ID 属性及其 getter 和 setter,那么一切正常。

Users.java

@Entity
@Table

public class Users {

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator= "generator")
@SequenceGenerator(name = "generator" , sequenceName="users_seq" , allocationSize=1)
private int user_id;

private String name,password,email,role,status,isOnline;

@OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JsonManagedReference
private List<Blog> blog = new ArrayList<Blog>();

@OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JsonManagedReference
private List<Forum> forum = new ArrayList<Forum>();

@OneToMany(mappedBy="user",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JsonManagedReference
private List<Friend> friend =  new ArrayList<Friend>();

public List<Forum> getForum() {
    return forum;
}

public List<Friend> getFriend() {
    return friend;
}

public void setFriend(List<Friend> friend) {
    this.friend = friend;
}

public void setForum(List<Forum> forum) {
    this.forum = forum;
}

public List<Blog> getBlog() {
    return blog;
}

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

public int getUser_id() {
    return user_id;
}

public void setUser_id(int user_id) {
    this.user_id = user_id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getRole() {
    return role;
}

public void setRole(String role) {
    this.role = role;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public String getIsOnline() {
    return isOnline;
}

public void setIsOnline(String isOnline) {
    this.isOnline = isOnline;
}

}

博客.java

@Entity
@Table
public class Blog {

@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator= "generator")
@SequenceGenerator(name = "generator" , sequenceName="blog_seq" , allocationSize=1)
private int blog_id;

private int likes,user_id; // I need to explicitly write the user_id column here

public int getUser_id() {
    return user_id;
}

public void setUser_id(int user_id) {
    this.user_id = user_id;
}

private String blog_name,blog_content,status;

@Temporal(TemporalType.DATE)
private Date create_date;

@ManyToOne
@JoinColumn(name="user_id",insertable=false, updatable=false) // This step will actually add the user_id column in the Blog model but it's not happening
@JsonBackReference
private Users user;

public Users getUser() {
    return user;
}

public void setUser(Users user) {
    this.user = user;
}

public int getBlog_id() {
    return blog_id;
}

public void setBlog_id(int blog_id) {
    this.blog_id = blog_id;
}

public int getLikes() {
    return likes;
}

public void setLikes(int likes) {
    this.likes = likes;
}

public String getBlog_name() {
    return blog_name;
}

public void setBlog_name(String blog_name) {
    this.blog_name = blog_name;
}

public String getBlog_content() {
    return blog_content;
}

public void setBlog_content(String blog_content) {
    this.blog_content = blog_content;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public Date getCreate_date() {
    return create_date;
}

public void setCreate_date(Date create_date) {
    this.create_date = create_date;
}

}

BlogDAOImpl.java

@EnableTransactionManagement
@Repository("blogDAO")
public class BlogDAOImpl implements BlogDAO {

@Autowired
SessionFactory sessionFactory;

public BlogDAOImpl(SessionFactory sessionFactory) {
    super();
    this.sessionFactory = sessionFactory;
}

public BlogDAOImpl() {
    super();
    // TODO Auto-generated constructor stub
}

@Transactional
public boolean addOrUpdateBlog(Blog blog) {
    try{
        sessionFactory.getCurrentSession().saveOrUpdate(blog);
        return true;
    }
    catch(Exception e)
    {
        System.out.println("Exception in addOrUpdateBlog of BlogDAOImpl");
        e.printStackTrace();
        return false;
    }
}

@Transactional
public boolean deleteBlog(Blog blog) {
    try
    {
        sessionFactory.getCurrentSession().delete(blog);
        return true;
    }
    catch(Exception e)
    {
        System.out.println("Exception in deleteBlog of BlogDAOImpl");
        e.printStackTrace();
        return false;
    }
}

@Transactional
public List<Blog> getListOfBlog() {
    try
    {
        String hql = "from Blog";
        Session session = sessionFactory.openSession();
        Query query = session.createQuery(hql);
        List<Blog> bloglist = query.list();
        session.close();
        return bloglist;
    }
    catch(Exception e)
    {
        System.out.println("Exception in getListOfBlog of BlogDAOImpl");
        e.printStackTrace();
        return null;
    }
}

@Transactional
public Blog getParticularBlog(int blogid) {
    try
    {
        return (Blog) sessionFactory.getCurrentSession().get(Blog.class, blogid);
    }
    catch(Exception e)
    {
        System.out.println("Exception in getParticularBlog of BlogDAOImpl");
        e.printStackTrace();
        return null;
    }
    }

}

博客 REST 控制器

package com.coding.blogandforum.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.coding.blogandforum.DAO.BlogDAO;
import com.coding.blogandforum.DAO.UserDAO;
import com.coding.blogandforum.model.Blog;
import com.coding.blogandforum.model.Users;

@RestController
public class BlogController {

    @Autowired
    BlogDAO blogDAO;

    @Autowired
    Blog blog;

    @Autowired
    Users user;

    @Autowired
    UserDAO userDAO;

    // To get the list of all the blog objects
    @RequestMapping(value="/getListOfBlog", method=RequestMethod.GET)
    public ResponseEntity<List<Blog>> getListOfBlog()
    {
        List<Blog> bloglist = blogDAO.getListOfBlog();
        return new ResponseEntity<List<Blog>>(bloglist,HttpStatus.OK);
    }

    /*
     * To get a particular Blog details using blog id
     * In postman, blog details are only displayed.
    */
    @RequestMapping(value="/getParticularBlog/{blogid}", method=RequestMethod.GET)
    public ResponseEntity<Blog> getParticularBlog(@PathVariable("blogid") int blogid)
    {
        Blog particularblog = blogDAO.getParticularBlog(blogid);
        return new ResponseEntity<Blog>(particularblog,HttpStatus.OK);
    }

    /* 
     * To get a particular user details with blogid 
     * In postman the user will display the blog and forum details along with it
     */
    @RequestMapping(value="/getUserDetailsWithBlogid/{blogid}", method=RequestMethod.GET)
    public ResponseEntity<Users> getUserDetailsWithBlogid(@PathVariable("blogid") int blogid)
    {
        Blog blogwithuser = blogDAO.getParticularBlog(blogid);
        return new ResponseEntity<Users>(blogwithuser.getUser(),HttpStatus.OK);
    }

    // To add a particular blog details in the DB
    @RequestMapping(value="/addBlog", method=RequestMethod.POST)
    public ResponseEntity<String> addBlog(@RequestBody Blog blog)
    {
        System.out.println(blog.getUser());
        blog.setStatus("PENDING");
        blogDAO.addOrUpdateBlog(blog);
        return new ResponseEntity<String>("Blog added successfully",HttpStatus.OK);
    }

    // To delete a particular blog from the DB
    @RequestMapping(value="/deleteBlog/{blogid}", method=RequestMethod.DELETE)
    public ResponseEntity<String> deleteBlog(@PathVariable("blogid") int blogid)
    {
        blogDAO.deleteBlog(blogDAO.getParticularBlog(blogid));
        return new ResponseEntity<String>("Blog deleted successfully",HttpStatus.OK);
    }

    /*
     * To update a particular blog
     * Date will not be displayed as YYYY-MM-DD in postman since the updateblog date property is not temporal
     */
    @RequestMapping(value="/updateBlog/{blogid}", method=RequestMethod.PUT)
    public ResponseEntity<Blog> updateBlog(@PathVariable("blogid") int blogid, @RequestBody Blog blog)
    {
        Blog updateblog = blogDAO.getParticularBlog(blogid);
        //updateblog.setBlog_content(blog.getBlog_content());
        updateblog.setCreate_date(blog.getCreate_date());
        blogDAO.addOrUpdateBlog(updateblog);
        return new ResponseEntity<Blog>(updateblog,HttpStatus.OK);
    }
}

删除可更新和可插入属性时的错误:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.coding.blogandforum.model.Blog column: user_id (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:709)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:731)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:753)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:506)
at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1358)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1849)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:372)
at com.coding.blogandforum.config.DBConfig.getSessionFactory(DBConfig.java:74)
at com.coding.blogandforum.config.DBConfig$$EnhancerBySpringCGLIB$$f06b8326.CGLIB$getSessionFactory$1(<generated>)
at com.coding.blogandforum.config.DBConfig$$EnhancerBySpringCGLIB$$f06b8326$$FastClassBySpringCGLIB$$96e5acd.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
at com.coding.blogandforum.config.DBConfig$$EnhancerBySpringCGLIB$$f06b8326.getSessionFactory(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 51 more

【问题讨论】:

  • 我认为您需要 referencedColumnName @ManyToOne @JoinColumn(name="user_id", referencedColumnName="user_id")
  • 它的行为与您指定的完全一样:insertable=false, updatable=false
  • 除此之外,我是否还需要在博客模型中拥有 user_id 列及其 getter 和 setter 方法? @KaushalNiraula
  • 我必须使用可插入和可更新属性,因为当我在没有这些属性的情况下运行程序时会出错。

标签: java hibernate spring-orm


【解决方案1】:

您可以像下面的代码一样使用 OneToOne 和 OneToMany:-

@OneToMany(mappedBy = "FOrder", cascade = CascadeType.ALL, fetch =  FetchType.LAZY)
private List<FOrderDetail> FOrderDetails;

@ManyToOne
@JoinColumn(name = "OFFER_ID")
private FOffer FOffer;

【讨论】:

    猜你喜欢
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    相关资源
    最近更新 更多