如何对@OneToMany

时间:2019-04-16 16:34:11

标签: java hibernate spring-boot jpa

我有一个 @OneToMany 关系,其中 @Many 端在数据库中必须是唯一的。每当我尝试使用现有的 @Many 实体持久化 @One 实体时,冬眠都会尝试再次持久化 @Many 一侧,并中断数据库完整性。我需要自动检查 @Many 端是否存在,如果存在,则仅链接两个实体。

考虑一个 Studio 对象,该对象可以具有许多 Tag 对象。每个 Tag 在数据库中都是唯一的,并且可以链接到许多 Studio (以及其他实体)。 Tag 仅链接到给定的 Studio 一次。当前,如果我使用相同的 Tag 坚持使用2个不同的 Studio ,则 Tag 会两次插入数据库,这会破坏其完整性。如何设计关系以确保 @Many 端的唯一性?我可以在DAO层中手动检查它,但我希望休眠状态可以解决它(有很多与Tag相似的属性,手动执行检查会使代码难以读/写)

我有5个共享相似属性的实体,这些实体归为一个共同的父对象:

public abstract class AbstractMovieEntity<T extends AbstractMovieEntity> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @NonNull
    @Column(unique = true, nullable = false)
    protected String name;

    @EqualsAndHashCode.Exclude
    @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
    protected Set<EntityTag> tags = new HashSet<>();

    ...

工作室是以上内容的专业化

@EqualsAndHashCode(callSuper=true)
@Getter
@Setter
@Entity
@NoArgsConstructor
public class Studio extends AbstractMovieEntity<Studio> {

 ...

}

我写了一个模拟实际应用的测试


    @Autowired
    private EntityManager entityManager;

    @Test
    public void studioTagsAreNotDuplicated() {
        Studio warners = new Studio("Warner Bros.");
        warners.addTag("Great Movies");

        Studio marvel = new Studio("Marvel");
        marvel.addTag("Great Movies");

        entityManager.persist(warners);
        entityManager.persist(marvel);  // <-- ConstraintViolationException

        ...
    }

以上结果导致ConstraintViolationException,因为第二个entityManager.persist调用尝试再次保留Tag。如果我尝试将entityManager.persist更改为entityManager.merge,则会遇到相同的问题。我能正确表示这种关系吗?我希望休眠在尝试插入之前检查标记是否存在,然后链接数据库中的两个实体。

这些表的定义如下:


CREATE TABLE STUDIO (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    name varchar(255) not null,
    description varchar,
    master_id BIGINT REFERENCES STUDIO(id),
    image_collection_id BIGINT REFERENCES IMAGE_COLLECTION(id)
);

CREATE TABLE ENTITY_TAG (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY,
    tag varchar(255) not null UNIQUE
);

CREATE TABLE STUDIO_TAGS (
    studio_id BIGINT REFERENCES STUDIO(id),
    tags_id BIGINT REFERENCES ENTITY_TAG(id)
);

感谢您的帮助

0 个答案:

没有答案
相关问题