当前位置: 首页 > 知识库问答 >
问题:

Hibernate持久性属性拦截器使可连接不工作

乐正育
2023-03-14

我使用springboot(2.1.9。RELEASE)和hibernate(5.4.6。最终)来开发程序,我需要懒加载一个字符串类型字段(更改日志),所以我使用了持久性属性截取表,字符串类型字段可以懒加载,但是ManyTo很多的连接表不起作用。这是代码

@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);
  }
}

运行测试用例后,数据被插入到类别和项目表中,但是joinTablecategory_items没有数据。如果项目不使用持久性属性属性,数据可以写入类别项目表,但是更改日志不能延迟加载。

共有1个答案

何浩荡
2023-03-14

我对@OneToMany而不是@ManyToMany(Hibernate 5.4.2)也有类似的问题。我猜是冬眠虫。如果使用PersistentAttributeInterceptable,那么在没有拦截器的情况下,就不能在这个类中使用延迟加载。尝试@ManyToMany(fetch=FetchType.eanger)不应该奏效。但这可能不是你想要的,因为你仍然有急于加载的性能问题。

 类似资料:
  • 我实现了一个Hibernate拦截器(扩展了EmptyInterceptor)并实现了onFlushDirty方法,以便在保存对象时将该对象的属性设置为null。代码如下所示: 不幸的是,即使我取消了对象的值,记录仍然保存到数据库中。奇怪的是,当我修改该对象时,更改被保存到数据库中。 对象和属性都是实体。

  • 问题内容: 我想对集合属性进行持久性操作,由我自己决定是否可以与数据库同步,并在确定一次持久性在所有集合上而不是每个元素上都发生持久性时调用一个过程。 怎么做 ? 这些集合属性通常使用一对多或多对多关联进行映射。所以,当我们有这样的事情: 对于具有两个类(实体)和单向多对多关联的映射,我只希望发生两个sql语句:和,期望接收以逗号分隔的值列表,该列表是来自上面的收藏。键集合只能保存在该系统上,该系

  • 我创建了一个小的Tcp通信应用程序,链接如下。 从此处编辑 其他TCPConnectionEvents的连接工厂属性似乎是正确的。例如,TcpConnectionCloseEvent日志如下所示。

  • 问题内容: 我正在尝试创建事务管理器,并将其与Hibernate for Oracle一起使用。 我的persistence.xml文件是: 在spring的applicationContext.xml中,我添加了: 但是,当我运行时: 我有一个例外: Hibernate基础文件文件除外。 可能是什么问题呢? Hibernate持久性如何知道引用Spring bean? 问题答案: 持久性提供程序

  • 我正在尝试设置一个属性,该属性将由我的功能测试中的每个方法使用。问题是它在测试之间并没有持续。 这是我的测试类: 我只希望属性在该类中的所有测试中保持不变。

  • 问题内容: 我想在我们的其中一台Web服务器上进行一些性能测试,以了解服务器如何处理大量持久连接。不幸的是,我对HTTP和Web测试不是很熟悉。这是到目前为止我已经获得的Python代码: 我的主要问题是: 如何保持这些连接的生命? 我设置了很长的超时时间,但这是一种非常粗糙的方法,我甚至不确定它是否会影响连接。是否只是偶尔偶尔请求一两个字节? (此外,与我代码末尾的丑陋块相比,还有一个更好的过程