Java hibernate PersistentAttributeInterceptor使jointable无法工作
我使用springboot(2.1.9.RELEASE)和hibernate(5.4.6.Final)来开发这个程序,我需要懒散地加载一个字符串类型字段(changelog),所以我使用PersistentAttribute Interceptable,字符串类型字段可以是懒散加载,但许多人的连接表不起作用。下面是代码Java hibernate PersistentAttributeInterceptor使jointable无法工作,java,hibernate,jpa,Java,Hibernate,Jpa,我使用springboot(2.1.9.RELEASE)和hibernate(5.4.6.Final)来开发这个程序,我需要懒散地加载一个字符串类型字段(changelog),所以我使用PersistentAttribute Interceptable,字符串类型字段可以是懒散加载,但许多人的连接表不起作用。下面是代码 @Entity @Table(name = "categories") public class Category implements Serializable { pr
@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;
}
}
@实体
@表(name=“categories”)
公共类类别实现可序列化{
私有静态最终长serialVersionUID=911243379555328411L;
@身份证
@列(name=“id”)
私人长id;
私有字符串名称;
私人职位;
@许多酮
@JoinColumn(name=“parent\u id”)
私人类别家长;
@OneToMany(mappedBy=“parent”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@OrderColumn(name=“position”)
列出儿童名单;
@许多(mappedBy=“类别”)
私人设置项目;
//接二连三
}
@实体
@表(name=“items”)
公共类项实现可序列化的PersistentAttributeInterceptable{
私有静态最终长serialVersionUID=6129011836002505114L;
@身份证
@列(name=“id”)
私人长id;
@列(name=“table_name”)
私有字符串表;
@列(name=“description”)
私有字符串描述;
@高球
@基本(fetch=FetchType.LAZY)
私有字符串更改日志;
@许多
@JoinTable(name=“category\u items”,joinColumns=@JoinColumn(name=“item\u id”,referencedColumnName=“id”),inverseJoinColumns=@JoinColumn(name=“category\u id”,referencedColumnName=“id”))
私有集合类别;
@短暂的
私有PersistentAttributeInterceptor拦截器;
//id、表、描述getter setter
公共字符串getChangelog(){
if(拦截器!=null){
return(String)interceptor.readObject(这个“changelog”,changelog);
}
返回null;
}
公共void setChangelog(字符串changelog){
if(changelog==null){
if(拦截器!=null){
interceptor.writeObject(this,“changelog”,this.changelog,changelog);
返回;
}
}
this.changelog=changelog;
}
公共集合getCategories(){
if(null==类别){
categories=新HashSet();
}
if(拦截器!=null){
return(Set)interceptor.readObject(这是“categories”,categories);
}
退货类别;
}
公共无效集合类别(集合类别){
如果(类别==null){
if(拦截器!=null){
interceptor.writeObject(this,“categories”,this.categories,categories);
返回;
}
}
这个。类别=类别;
}
@凌驾
公共PersistentAttributeInterceptor$$\u hibernate\u getInterceptor(){
返回拦截器;
}
@凌驾
public void$$\u hibernate\u setInterceptor(persistenttributeinterceptor persistenttributeinterceptor){
拦截器=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);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(类=Application.class)
公共类ItemRepositoryTest{
@自动连线项目存储库项目存储库;
@自动连线分类存储分类存储;
@交易的
@回滚(false)
@试验
公共作废保存(){
类别根=构建类别(1L,“根”,0);
类别child1=建筑类别(2L,“child1”,1);
类别child2=建筑类别(3L,“child2”,2);
类别child3=建筑类别(4L,“child3”,3);
List children=Arrays.asList(child1、child2、child3);
根。setChildren(children);
List categories1=Arrays.asList(root、child1、child2、child3);
categoryRepository.saveAll(类别1);
categoryRepository.flush();
项目=建筑项目(1L,“安全”、“测试”);
Set categories=新的HashSet();
类别.增加(儿童1);
项目.集合类别(类别);
itemRepository.saveAndFlush(项目);
资产真实(真实);
}
}
在运行测试用例之后,数据被插入到categories和items表中,但是joinTable category\u项没有数据。
如果项不使用PersistentAttributeAttributeTable,则可以将数据写入类别项表,但不能延迟加载changelog。我对@OneToMany而不是@ManyToMany(使用Hibernate 5.4.2)有类似的问题。我猜这是一只冬眠虫。如果您使用PersistentAttributeInterceptable,那么在没有拦截器的情况下,您就不能在此类中使用延迟加载。尝试@ManyToMany(fetch=FetchType.EAGER)比它应该能工作的多。但这可能不是您想要的,因为您仍然存在着急于加载的性能问题