英文:
Spring Many to Many Association DTO Conversion
问题
我在Spring中使用Hibernate进行持久化,有一个标准的多对多关系。为了简洁起见,构造函数和setter方法被省略。
@Entity
@Table(name = "a")
public class A {
@ManyToMany(mappedBy = "as")
private Set<B> bs;
}
@Entity
@Table(name = "bs")
public class B {
@ManyToMany
@JoinTable(
name = "b_a",
joinColumns = @JoinColumn(name = "b_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "a_id", referencedColumnName = "id")
)
private Set<A> as = new HashSet<>();
}
我还为每个类创建了DTO,并且我有用于在它们之间进行转换的静态方法。由于多对多关系,我需要实现一种状态跟踪器,以防止程序陷入无限递归。
public final class DTOEntityMapper {
private static class StateHolder {
private List<Object> alreadySeenObjects = new ArrayList<>();
void addObject(Object o){
alreadySeenObjects.add(o);
}
boolean contains(Object o){
return alreadySeenObjects.contains(o);
}
}
public static BDTO fromBToDTO(B b) {
return fromBToDTO(b, new StateHolder());
}
private static BDTO fromBToDTO(B b, StateHolder state) {
state.addObject(b);
return BDTO.builder()
.withAs(b.getAs().stream().filter(item -> !state.contains(item)).map(e -> fromAToDTO(e, state)).collect(Collectors.toSet()))
.build();
}
}
// 注意:fromAToDTO执行相同的操作。
然而,当我尝试测试时,出现了断言失败:
@Test
public void convertFromBToBDTO() {
A a = new A("a");
B b = new B("b");
b.setAs(ImmutableSet.of(a));
a.setBs(ImmutableSet.of(b));
ADTO aDTO = new ADTO("a");
BDTO bDTO = new BDTO("b");
bDTO.setAs(ImmutableSet.of(aDTO));
aDTO.setBs(ImmutableSet.of(bDTO));
BDTO expected = bDTO;
assertThat(DTOEntityMapper.fromBToDTO(b)).isEqualTo(expected);
}
实际结果:BDTO{as=[ADTO{bs=}]}
预期结果:BDTO{as=[ADTO{bs=b1}]}
基本上,我对在数据模型和DTO之间进行转换时如何处理多对多关系感到困惑。希望这能够理解!
英文:
I have a standard many to many relationship in Spring with persistence using Hibernate. Constructors and setters left out for brevity.
@Entity
@Table(name = "a")
public class A {
@ManyToMany(mappedBy = "as")
private Set<B> bs;
}
@Entity
@Table(name = "bs")
public class B {
@ManyToMany
@JoinTable(
name = "b_a",
joinColumns = @JoinColumn(name = "b_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "a_id", referencedColumnName = "id")
)
private Set<A> as = new HashSet<>();
}
I also have DTOs for each of these classes and I have static methods to transfer between them. Due to the many-to-many relationship, I need to implement a form of state tracker to stop the program getting caught in infinite recursion.
public final class DTOEntityMapper {
private static class StateHolder {
private List<Object> alreadySeenObjects = new ArrayList<>();
void addObject(Object o){
alreadySeenObjects.add(o);
}
boolean contains(Object o){
return alreadySeenObjects.contains(o);
}
}
public static BDTO fromBToDTO(B b) {
return fromBToDTO(b, new StateHolder());
}
private static BDTO fromBToDTO(B b, StateHolder state) {
state.addObject(b);
return BDTO.builder()
.withAs(b.getAs().stream().filter(item -> !state.contains(item)).map(e -> fromAToDTO(e, state)).collect(Collectors.toSet()))
.build();
}
}
// Note: fromAToDTO does same thing.
However when I try and test I get an assertion failure:
@Test
public void convertFromBToBDTO() {
A a = new A("a");
B b = new B("b");
b.setAs(ImmutableSet.of(a));
a.setBs(ImmutableSet.of(b));
aDTO ADTO = new ADTO("a");
bDTO BDTO = new BDTO("b");
bDTO.setAs(ImmutableSet.of(aDTO));
aDTO.setBs(ImmutableSet.of(bDTO));
BDTO expected = bDTO;
assertThat(DTOEntityMapper.fromBToDTO(b)).isEqualTo(expected);
}
Actual: BDTO{as=[ADTO{bs=}]}
Expected: BDTO{as=[ADTO{bs=b1}]}
Basically I am confused with how I deal with many-to-many relationships when converting between the data model and DTOs. Hopefully this makes sense!
专注分享java语言的经验与见解,让所有开发者获益!
评论