【问题标题】:hibernate PersistentAttributeInterceptor make jointable not work休眠 PersistentAttributeInterceptor 使可连接不起作用
【发布时间】: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不能懒加载。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    @OneToMany 而不是@ManyToMany(使用 Hibernate 5.4.2)我也有类似的问题。我猜这是一个休眠错误。如果你使用 PersistentAttributeInterceptable,那么你就不能在没有拦截器的情况下在这个类中使用延迟加载。尝试 @ManyToMany(fetch = FetchType.EAGER) 比它应该工作。但这可能不是您想要的,因为您仍然遇到 EAGER Loading 的性能问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2015-10-28
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多