如何使用关系OneToOne将两个相关对象保存到数据库

时间:2019-07-02 05:08:38

标签: java hibernate spring-boot spring-data-jpa

当我尝试保存U对象时,出现下一个异常:

org.springframework.orm.jpa.JpaSystemException:尝试从空的一对一属性[com.roc.domain.A.user]分配ID;嵌套的异常是org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性[com.roc.domain.A.user]中分配ID。

我有两个表:  1.用户,其列为id(自动增量,主要),名称。  2.与该列联系的是id,user_id(即外键-> user.id)和地址。

@Entity
@Table(name = "a")
public class A {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Long id;

  @Column(name="address")
  private String address;

  @OneToOne
  @MapsId
  private U user;

  public A() {

  }
   // getters and setters



}


@Entity
@Table(name = "u")
public class U {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Long id;
  @Column(name="username")
  private String userName;
  @JoinColumn(name = "user_id", referencedColumnName = "id")
  @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
  private A a;

  public U(){};

}

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {

  @Autowired
  private URepository uRepository;

  @Test
  public void simpleCrudTest() {
    U user = new U("name", new A("address"));
    uRepository.save(user);


  }
}

2 个答案:

答案 0 :(得分:0)

编辑:要使用单个存储库保存调用。

    @Entity
@Table(name = "a")
public class A {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "address")
    private String address;

    @OneToOne
    @MapsId
    private U user;

    public A() {

    }
}

@Entity
@Table(name = "u")
public class U {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @Column(name = "username")
    private String userName;
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
    private A a;

    public U() {
    };

    // method to manage the bidirectional association
    public U addToA(A a) {
        this.a.add(a);
        a.setUser(this);

    }

}

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTest {

    @Autowired
    private URepository uRepository;

    @Test
    public void simpleCrudTest() {

        U user = new U();
        user.addToA(new A("address"));

        user.setUserName("username");
        uRepository.save(user);

    }
}

此外,您引用此链接。

inserting values into multiple tables using hibernate

      You have to save A first, Then set saved A to U and save U.    


        @RunWith(SpringRunner.class)
            @SpringBootTest
            public class ApplicationTest {

              @Autowired
              private URepository uRepository;

              @Autowired
              private ARepository aRepository;

              @Test
              @Trascational
              public void simpleCrudTest() {

                A a = new A();
                a.setAddress("address");
                a = aRepository.save(a);

                U user = new U("name", a);
                uRepository.save(user);


              }
            }

答案 1 :(得分:0)

您已经正确设置了级联,但是由于这种关系是双向的,因此您需要在内存模型中设置双方。

  @Test
  public void simpleCrudTest() {
    U user = new U("name", new A("address"));

   //will work when this is added 
   a.setUser(user);
   uRepository.save(user);

  }

否则,由于错误状态,A在保存时为用户提供了空引用。