我使用spring的crudepository来持久化一个对象(workingdays),它包含一个其他对象的列表(filter),基本上包含一组枚举。使用crudrepository的findall函数时,对象按预期进行组装;使用findbyid函数时,返回的workingdays对象包含错误的筛选器项列表
请参见下面的示例
package com.example.jpastackoverflow.model;
import lombok.Data;
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "working_days")
@Data
public class WorkingDays {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String someFiled;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "working_days_id")
private List<Filter> filterList;
}
package com.example.jpastackoverflow.model;
import lombok.Data;
import javax.persistence.*;
import java.util.Set;
@Entity
@Table(name = "filter")
@Data
public class Filter {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String someFiled;
@ElementCollection(targetClass = DAYS.class, fetch = FetchType.EAGER)
@CollectionTable(name = "filter_days",
joinColumns = @JoinColumn(name = "filter_id"))
@Column(name = "days")
@Enumerated(EnumType.STRING)
private Set<DAYS> days = null;
}
package com.example.jpastackoverflow.model;
public enum DAYS {
MONDAY(0),
TUESDAY(1),
WEDNESDAY(2),
THURSDAY(3),
FRIDAY(4),
SATURDAY(5),
SUNDAY(6);
private final Integer day;
DAYS(final Integer day) {
this.day = day;
}
public final Integer getDay() {
return day;
}
}
package com.example.jpastackoverflow.model;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
@Repository("Repository")
@Transactional
public interface Repo extends CrudRepository<WorkingDays, Long> {}
最后是测试:
@SpringBootTest
class WorkingDaysTest {
@Autowired
private Repo repo;
@BeforeEach
void setUp() {
Set<DAYS> days1 = new HashSet<>();
Set<DAYS> days2 = new HashSet<>();
days1.add(DAYS.MONDAY);
days1.add(DAYS.TUESDAY);
days1.add(DAYS.WEDNESDAY);
days2.add(DAYS.THURSDAY);
days2.add(DAYS.FRIDAY);
days2.add(DAYS.SATURDAY);
days2.add(DAYS.SUNDAY);
Filter filter1 = new Filter();
Filter filter2 = new Filter();
filter1.setSomeFiled("foo");
filter2.setSomeFiled("bar");
filter1.setDays(days1);
filter2.setDays(days2);
List<Filter> filterList = new ArrayList<>();
filterList.add(filter1); //just add one entry to the list (Mon, Tue, Wed)
filterList.add(filter2); //just add one entry to the list (Thu, Fri, Sat, Sun)
WorkingDays workingDays1 = new WorkingDays();
workingDays1.setSomeFiled("foo1");
workingDays1.setFilterList(filterList);
repo.save(workingDays1);
}
@Test
void findAll() {
Iterable<WorkingDays> it = repo.findAll();
it.forEach(wd -> System.out.println(wd.toString()));
/*
WorkingDays(id=1,
someFiled=foo1,
filterList=[
Filter(id=1, someFiled=foo, days=[TUESDAY, MONDAY, WEDNESDAY]),
Filter(id=2, someFiled=bar, days=[SUNDAY, THURSDAY, FRIDAY, SATURDAY])])
*/
}
@Test
void findById() {
Optional<WorkingDays> oWorkingDays1 = repo.findById(1L);
assertTrue(oWorkingDays1.isPresent());
System.out.println(oWorkingDays1.get().toString());
/*
WorkingDays(id=1,
someFiled=foo1,
filterList=[
Filter(id=1, someFiled=foo, days=[MONDAY, TUESDAY, WEDNESDAY]),
Filter(id=1, someFiled=foo, days=[MONDAY, TUESDAY, WEDNESDAY]),
Filter(id=1, someFiled=foo, days=[MONDAY, TUESDAY, WEDNESDAY]),
Filter(id=2, someFiled=bar, days=[SATURDAY, SUNDAY, THURSDAY, FRIDAY]),
Filter(id=2, someFiled=bar, days=[SATURDAY, SUNDAY, THURSDAY, FRIDAY]),
Filter(id=2, someFiled=bar, days=[SATURDAY, SUNDAY, THURSDAY, FRIDAY]),
Filter(id=2, someFiled=bar, days=[SATURDAY, SUNDAY, THURSDAY, FRIDAY])])
*/
}
}
findall用一个带有两个条目的“filterlist”来组装workingdays,就像它存储时一样(参见测试用例中的注解)。
findbyid用一个包含7个条目的“filterlist”来组装工作日。对于“days”集合中的每个条目,都会创建一个新的“filter”对象并将其添加到“filterslist”中(请参见测试用例中的注解)。
有人能解释为什么会发生这种情况并提出一个有效的解决方案吗?
1条答案
按热度按时间gmxoilav1#
这就是当你在一个袋子里找人加入一个社团时得到的。使用
Set<Filter> filterList;
而不是List<Filter> filterList;
为了避免这种情况。