Hibernate onetomany映射 [英] Hibernate onetomany mapping

查看:140
本文介绍了Hibernate onetomany映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试第一次映射关系。我发现了很多方法。

有两个类:
- Project(Parent)
- Application(Child)

所以一个项目可以有多个应用程序,但一个应用程序只属于一个项目。



我构建它们如下:

Project.java

  import javax.persistence.CascadeType; 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

@Entity
public class Project {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name =project_id,nullable = false)
@ org.hibernate.annotations.IndexColumn(name =project_index)
列表<应用程序> applications = new ArrayList< Application>();

[获取和设置方法...]
}

Application.java

  import javax.persistence.Entity; 
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Application {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@ManyToOne
@JoinColumn(name =project_id,updatable = false,insertable = false,nullable = false)
私人项目项目;

[获取和设置方法...]
}

...但不幸的是,我得到了一个我无法处理的异常:

  javax.servlet.ServletException:org.hibernate .PropertyValueException:not-null属性引用null或瞬态值:.... common.entities.Application._applicationsBackref 
javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
org .apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
org.apache.shiro.web.servlet.AbstractShiroFilter $ 1.call(AbstractShiroFilter.java:275)
org。 apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
org.apache。 shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
org.apache .shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)

根本原因

javax.faces.el.E​​valuationException:org.hibernate.PropertyValueException:not -null属性引用null或瞬态值:.... common.entities.Application._applicationsBackref
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:98)
com.sun.faces .application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
javax.faces.component.UICommand.broadcast(UICommand.java:311)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java :781)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
com .sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
javax.faces.webapp.FacesServlet .serv冰(FacesServlet.java:308)
org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
org.apache.shiro.web.servlet.AbstractShiroFilter $ 1.call (AbstractShiroFilter.java:275)
org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable .java:83)
org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java :272)
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)

根本原因

org.hibernate.PropertyValueException :not-null属性引用空值或瞬态值:.... common.entities.Application._applicationsBackref
org.hibernate.engine.Nullability.checkNullability(Nullability.java:95)
org.hibernate .event.def.AbstractSaveEventListener.performS aveOrReplicate AbstractSaveEventListener.java:
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
org.hibernate.event。 def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)

我的错误在哪里?我的意思是什么都没有。只有在项目方面






当我在拥有方移除@JoinColumn时,发生异常:

  java.sql.SQLException:Field'project_id'没有默认值






谢谢帕斯卡尔

解决方案

您的映射中有几件事需要解决。




  • 您的关联是双向的,您需要使用 mappedBy 属性(或者你会得到的是两个单向关联)来定义拥有关系的字段(拥有外键的那一面,即许多方面都是一对多的)。

  • @JoinColumn 注释只能在拥有者一方定义,而不能同时定义如果您使用的是Hibernate(即Hibernate 3.5+)的JPA 2.0兼容版本,则更喜欢标准的 @OrderColumn 注释。
  • 的Hiberna特定的 @IndexColumn
  • 我不确定要理解为什么定义 @JoinColumn 完全只读,并且 updatable = false,insertable = false,nullable = false ,这听起来不合适。


所以你的映射会变成(假设你使用的是JPA 2.0):

  public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@OneToMany(cascade = CascadeType.ALL, mappedBy =project)
@OrderColumn(name =project_index)

List< Application > applications = new ArrayList< Application>();

// getters,setters
}

  @Entity 
public class Application {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY )
private int id;

@ManyToOne
@JoinColumn(name =project_id)
私人项目项目;

// getters,setters
}

关联,是双向的,不要忘记在创建对象图时设置链接的两端:

  Project p = new项目(); 
Application a = new Application();
a.setProject(p);
p.getApplications()。add(a);
em.persist(p);

但我实际上建议在您的实体中创建链接管理方法来设置链接的两侧,例如

  @Entity 
public class Project {
...
public void addToApplications(应用程序应用程序){
this.applications.add(app);
app.setProject(this);
}
...
}



资源




  • Hibernate核心文档


  • JPA wiki book


    • OneToMany关系示例和ManyToOne注释



    • 参考文献




      • JPA 1.0规范


        • 第2.1.8.2节双向ManyToOne / OneToMany关系
        • 第9.1.24节OneToMany Annotation
        • 第9.1.22节ManyToOne批注


      • JPA 2.0规范


        • 第11.1.39节OrderColumn注解



      I try to map a relation for the first time. I have found a lot of ways to go.

      There are two classes: - Project (Parent) - Application (Child)

      So one project can have several applications, but one application belongs to just one project..

      I constructed them as follows:

      Project.java

       import javax.persistence.CascadeType;
          import javax.persistence.Entity;
          import javax.persistence.GeneratedValue;
          import javax.persistence.GenerationType;
          import javax.persistence.Id;
          import javax.persistence.JoinColumn;
          import javax.persistence.OneToMany;
      
          @Entity
          public class Project {
      
           @Id
           @GeneratedValue(strategy = GenerationType.IDENTITY)
           private int id;
              @OneToMany(cascade = CascadeType.ALL)
              @JoinColumn(name = "project_id", nullable=false)
              @org.hibernate.annotations.IndexColumn(name = "project_index")
              List<Application> applications = new ArrayList<Application>();
      
              [get and set methods...]
              }
      

      Application.java

      import javax.persistence.Entity;
          import javax.persistence.GeneratedValue;
          import javax.persistence.GenerationType;
          import javax.persistence.Id;
          import javax.persistence.JoinColumn;
          import javax.persistence.ManyToOne;
      
          @Entity
          public class Application {
      
               @Id
               @GeneratedValue(strategy = GenerationType.IDENTITY)
               private int id;
      
                  @ManyToOne
                  @JoinColumn(name = "project_id", updatable = false, insertable = false, nullable=false)
                  private Project project;
      
              [get and set methods...]
           }
      

      ...but, unfortunately I got an exception I can not deal with:

      javax.servlet.ServletException: org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref
       javax.faces.webapp.FacesServlet.service(FacesServlet.java:321)
       org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
       org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:275)
       org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
       org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
       org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
       org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
       org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)
      
      root cause
      
      javax.faces.el.EvaluationException: org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref
       javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:98)
       com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:98)
       javax.faces.component.UICommand.broadcast(UICommand.java:311)
       javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:781)
       javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1246)
       com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:77)
       com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
       com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
       javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
       org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:359)
       org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:275)
       org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
       org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
       org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:343)
       org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:272)
       org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:83)
      
      root cause
      
      org.hibernate.PropertyValueException: not-null property references a null or transient value: ....common.entities.Application._applicationsBackref
       org.hibernate.engine.Nullability.checkNullability(Nullability.java:95)
       org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:313)
       org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
       org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
       org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
       org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
       org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
       org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
       org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
      

      Where is my mistake? I mean there is nothing null. Only on project side


      When I remove @JoinColumn on owning side an exception occures:

      java.sql.SQLException: Field 'project_id' doesn't have a default value
      


      Thank you Pascal

      解决方案

      There are several things to fix in your mapping.

      • Your association is bidirectional, you need to use the mappedBy attribute on the "One" side (or what you'll get is two unidirectional associations) to define the field that "owns" the relation on the owning side (the side that holds the foreign key i.e. the Many side in a one-to-many).
      • The @JoinColumn annotation should be defined on the owning side only, not both sides.
      • If you are using a JPA 2.0 compliant version of Hibernate (i.e. Hibernate 3.5+), prefer the standard @OrderColumn annotation of the Hibernate specific @IndexColumn
      • I'm not sure to understand why you defined the @JoinColumn as totally read-only with updatable = false, insertable = false, nullable=false, this doesn't sound appropriate.

      So your mappings become (assuming you're using JPA 2.0):

      @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 = new ArrayList<Application>();
      
          // getters, setters
      }

      And

      @Entity
      public class Application {
      
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private int id;
      
          @ManyToOne
          @JoinColumn(name = "project_id")
          private Project project;
      
          // getters, setters
       }
      

      And since your association, is bidirectional, don't forget to set both sides of the link when creating your object graph:

      Project p = new Project();
      Application a = new Application();
      a.setProject(p);
      p.getApplications().add(a);
      em.persist(p);
      

      But I would actually recommend to create link management methods in your entities to set both sides of the link, e.g.

      @Entity
      public class Project {
          ...
          public void addToApplications(Application app) {
              this.applications.add(app);
              app.setProject(this);
          }
          ...
      }
      

      Resources

      References

      • JPA 1.0 specification
        • Section 2.1.8.2 "Bidirectional ManyToOne / OneToMany Relationships"
        • Section 9.1.24 "OneToMany Annotation"
        • Section 9.1.22 "ManyToOne Annotation"
      • JPA 2.0 specification
        • Section 11.1.39 "OrderColumn Annotation"

      这篇关于Hibernate onetomany映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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