一对一MapSpring Data JPA

8i9zcol2  于 7个月前  发布在  Spring
关注(0)|答案(3)|浏览(55)

我有一个关于Sping Boot 中的One to One单向Map的问题。我有一个Customer类,它具有到Address类的One to One单向Map。
但是当我尝试将一个新客户与一个现有的地址关联时,数据库会被更新,所以两个客户现在与一个地址关联。
据我所知,只有一个客户应该与一个唯一的地址相关联。我是否正确理解了这个概念,或者我在Sping Boot / Spring Data JPA/ Hibernate中做错了什么?

客户

@Entity
public class Customer {
    @Id
    private Long cId;
    private String cName;
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="aid")
    private Address cAddr;
    :
}

字符串

地址

@Entity
public class Address {
    @Id
    private Long aid;
    private String town;
    private String county;
    :
}

data.sql

insert into address values (100, "New York", "NY");
insert into customer values (1, "John Smith", 100);

应用程序.java

@Override
public void run(String... args) throws Exception {
    Customer c1 = new Customer((long)5, "Mr. Men");
    Optional<Address> a100 = ar.findById((long)100);
    c1.setcAddr(a100.get());
    cr.save(c1);
}

数据库x1c 0d1x

zf2sa74q

zf2sa74q1#

有两种方法可以让@OneToOne建立关系:单向和双向:参见hibernate文档。
当你向下滚动一点,你会发现以下内容:
当使用双向@OneToOne关联时,Hibernate在获取子端时强制执行唯一约束。如果有多个子端与同一父端关联,Hibernate将抛出org.hibernate.exception。
这意味着只有在获取和双向关联时才会有异常。因为Hibernate会进行额外的查询来查找依赖实体,会找到其中的2个,这不符合@OneToOne关系,必须抛出异常。
“修复”实体唯一性的一种方法是使cAddr唯一:

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="aid", unique=true)
private Address cAddr;

字符串
如果创建数据库表,通过setting hbm2ddl property,这将向aid列添加唯一约束。
我真的建议阅读以下内容:
1.@OneToOne javadoc本身提供了如何正确执行所有操作的示例(对您来说,示例1和2是最有用的)
1.检查Vlad's blog about @OneToOne。它必须是你能找到的最好的。至少跳到“最有效的Map”一章,并使用@MapsId实现双向和共享PK。
也可能你会想出使用@ManyToOne选项的想法(至少我可以想象客户可以有多个地址)

zed5wv10

zed5wv102#

这不是One-to-Many关系。它是One-to-Many,因为 * 一个 * 对象有 * 多个 * 相关对象。Checkout this article
示例如下:

Post.java

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Post {

    @Id
    @GeneratedValue
    @Column(name = "post_id")
    private Long id;

    @Column
    private String postHeader;

    @OneToMany(
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<Comment> comments = new ArrayList<>();

    public void addComment(Comment comment) {
        comments.add(comment);
    }

    public void removeComment(Comment comment) {
        comments.remove(comment);
    }

    // equals() and hashCode()
}

字符串

评论:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Comment {

    @Id
    @GeneratedValue
    @Column(name = "postcom_id")
    private Long id;

    @Column
    private String text;

    // equals() and hashCode()
}

qnzebej0

qnzebej03#

在这个site中查看步骤“3.单向一对一Map演示”,基本上是你要做的事情的副本。

相关问题