【发布时间】:2019-10-09 02:25:30
【问题描述】:
我使用springboot(2.1.9.RELEASE)和hibernate(5.4.6.Final)开发程序,并且需要lazyload一个String类型字段(changelog),所以我使用PersistentAttribute Interceptable,string类型字段可以懒加载,但是ManyToMany的join Table不起作用。这里是代码
@Entity
@Table(name = "categories")
public class Category implements Serializable {
private static final long serialVersionUID = 911243379555328411L;
@Id
@Column(name = "id")
private Long id;
private String name;
private int position;
@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OrderColumn(name = "position")
List<Category> children;
@ManyToMany(mappedBy = "categories")
private Set<Item> items;
// getter AND setter
}
@Entity
@Table(name = "items")
public class Item implements Serializable, PersistentAttributeInterceptable {
private static final long serialVersionUID = 6129011836002505114L;
@Id
@Column(name = "id")
private Long id;
@Column(name = "table_name")
private String table;
@Column(name = "description")
private String description;
@Lob
@Basic(fetch = FetchType.LAZY)
private String changelog;
@ManyToMany
@JoinTable(name = "category_items", joinColumns = @JoinColumn(name = "item_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "category_id", referencedColumnName = "id"))
private Set<Category> categories;
@Transient
private PersistentAttributeInterceptor interceptor;
// id, table, description getter setter
public String getChangelog() {
if (interceptor != null) {
return (String) interceptor.readObject(this, "changelog", changelog);
}
return null;
}
public void setChangelog(String changelog) {
if (changelog == null) {
if (interceptor != null) {
interceptor.writeObject(this, "changelog", this.changelog, changelog);
return;
}
}
this.changelog = changelog;
}
public Set<Category> getCategories() {
if (null == categories) {
categories = new HashSet<>();
}
if (interceptor != null) {
return (Set<Category>) interceptor.readObject(this, "categories", categories);
}
return categories;
}
public void setCategories(Set<Category> categories) {
if (categories == null) {
if (interceptor != null) {
interceptor.writeObject(this, "categories", this.categories, categories);
return;
}
}
this.categories = categories;
}
@Override
public PersistentAttributeInterceptor $$_hibernate_getInterceptor() {
return interceptor;
}
@Override
public void $$_hibernate_setInterceptor(PersistentAttributeInterceptor persistentAttributeInterceptor) {
interceptor = persistentAttributeInterceptor;
}
}
测试用例代码
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class ItemRepositoryTest {
@Autowired ItemRepository itemRepository;
@Autowired CategoryRepository categoryRepository;
@Transactional
@Rollback(false)
@Test
public void save() {
Category root = buildCategory(1L, "root", 0);
Category child1 = buildCategory(2L, "child1", 1);
Category child2 = buildCategory(3L, "child2", 2);
Category child3 = buildCategory(4L, "child3", 3);
List<Category> children = Arrays.asList(child1, child2, child3);
root.setChildren(children);
List<Category> categories1 = Arrays.asList(root, child1, child2, child3);
categoryRepository.saveAll(categories1);
categoryRepository.flush();
Item item = buildItem(1L, "SecuMain", "test");
Set<Category> categories = new HashSet<>();
categories.add(child1);
item.setCategories(categories);
itemRepository.saveAndFlush(item);
assertTrue(true);
}
}
运行测试用例后,数据被插入到categories 和items 表中,但是joinTable category_items 没有数据。 如果Item不使用PersistentAttributeAttributeable,数据可以写入category-items表,但是changelog不能懒加载。
【问题讨论】: