在测试方法中声明@Transaction时,为什么不以多对多关系保留联接表?

时间:2019-06-10 13:38:28

标签: hibernate jpa spring-data-jpa

为什么在测试方法中声明@Transaction时,不以多对多关系保留联接表?

下面是我的实体类代码。

当我声明@Transaction时,Hibernate将值插入到联接表中。但是,如果我不声明它,请不要插入它。

@Entity
@Table(name = "parent")
public class ParentEntity {

    @Id
    @Column(name = "parent_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column
    private String parentValue;

    @OneToMany(mappedBy = "parentEntity", cascade = CascadeType.PERSIST)
    private List<ChildEntity> childs = new ArrayList<>();
}

@Entity
@Table(name = "child")
public class ChildEntity {

    @Id
    @Column(name = "child_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column
    private String childValue;

    @ManyToOne
    @JoinColumn(name="parent_id")
    private ParentEntity parentEntity;


    @ManyToMany(cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "child_tag",
            joinColumns = @JoinColumn(name = "child_id", nullable = false),
            inverseJoinColumns = @JoinColumn(name = "tag_id", nullable = false)
    )
    private Set<TagEntity> tags;
}

@Entity
@Table(name = "Tag")
public class TagEntity {

    @Column(name = "tag_id")
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    long tagId;

    @Column
    String value;

    @ManyToMany(mappedBy = "tags")
    private List<ChildEntity> childs;
}

@Transactional O

Hibernate: insert into parent (parent_value) values (?)
Hibernate: insert into child (child_value, parent_id) values (?, ?)
Hibernate: insert into tag (value) values (?)
Hibernate: insert into tag (value) values (?)
Hibernate: insert into tag (value) values (?)
Hibernate: insert into child (child_value, parent_id) values (?, ?)

@Transcational X

Hibernate: insert into parent (parent_value) values (?)
Hibernate: insert into child (child_value, parent_id) values (?, ?)
Hibernate: insert into tag (value) values (?)
Hibernate: insert into tag (value) values (?)
Hibernate: insert into tag (value) values (?)
Hibernate: insert into child (child_value, parent_id) values (?, ?)
Hibernate: insert into child_tag (child_id, tag_id) values (?, ?)
Hibernate: insert into child_tag (child_id, tag_id) values (?, ?)
Hibernate: insert into child_tag (child_id, tag_id) values (?, ?)

下面是我的测试代码。

@Repository
@Transactional
public class TestRepository {
    @Autowired
    private EntityManager em;

    public void saveParent(ParentEntity parent) {
        em.persist(parent);
    }
}


@Autowired
TestRepository repository;

@Test
@Transactional // @Transactional
    public void test() {
        ParentEntity parentEntity = new ParentEntity();
        parentEntity.setParentValue("parent value");

        ChildEntity childEntity1 = new ChildEntity();
        childEntity1.setChildValue("child1 value");

        ChildEntity childEntity2 = new ChildEntity();
        childEntity2.setChildValue("child2 value");

        TagEntity tagEntity = new TagEntity();
        tagEntity.setValue("tag1 value");

        TagEntity tagEntity2 = new TagEntity();
        tagEntity.setValue("tag2 value");

        TagEntity tagEntity3 = new TagEntity();
        tagEntity.setValue("tag3 value");

        Set<TagEntity> tags1 = new HashSet<>();
        tags1.add(tagEntity);
        tags1.add(tagEntity2);

        Set<TagEntity> tags2 = new HashSet<>();
        tags1.add(tagEntity2);
        tags1.add(tagEntity3);

        childEntity1.setTags(tags1);
        childEntity2.setTags(tags2);

        tagEntity.setChilds(Collections.singletonList(childEntity1));
        tagEntity2.setChilds(Arrays.asList(childEntity1, childEntity2));
        tagEntity3.setChilds(Collections.singletonList(childEntity2));

        childEntity1.setParentEntity(parentEntity);
        childEntity2.setParentEntity(parentEntity);

        parentEntity.getChilds().add(childEntity1);
        parentEntity.getChilds().add(childEntity2);

        repository.saveParent(parentEntity);
    }

1 个答案:

答案 0 :(得分:0)

EntityManager.persist()是“逻辑”操作,并非强制触发插入语句。

仅flush()和事务提交会触发SQL语句的执行。

因此,如果您不希望提交事务并查看所有插入语句,则必须调用EntityManager.flush()