Spring中@CollectionTable的updatable=false不生效,如何禁用自动保存?
解决方案
要让Hibernate完全不自动维护这个@ElementCollection集合的持久化,仅通过原生SQL管理数据,可以试试以下方法:
1. 使用@Immutable注解(推荐)
在集合字段的@ElementCollection上方添加@Immutable注解,这个注解会明确告诉Hibernate该集合是只读的,不会对其执行任何插入、更新或删除操作,完全交由你通过原生SQL维护关联表数据。
修改后的代码如下:
@NotAudited @Immutable @ElementCollection(fetch = FetchType.LAZY) @Column(name = "user_id") @CollectionTable(name = "crm_contact_list_user_included_items_ids", joinColumns = {@JoinColumn(name="contact_list_id")}) protected Set<Long> userIncludedItemsIds = new HashSet<>();
你之前设置的insertable=false和updatable=false之所以没生效,是因为@ElementCollection的默认逻辑是Hibernate会跟踪集合的变化并同步到数据库,这些字段级的设置无法完全覆盖集合的生命周期管理,而@Immutable是从集合层面直接标记只读,能彻底禁用Hibernate的自动保存行为。
2. 备选方案:将集合设为不可修改
如果你不想用@Immutable,也可以在初始化集合时使用不可修改的实现,同时配合字段级的只读设置,进一步降低Hibernate尝试修改的概率:
@NotAudited @ElementCollection(fetch = FetchType.LAZY) @Column(name = "user_id", insertable = false, updatable = false) @CollectionTable(name = "crm_contact_list_user_included_items_ids", joinColumns = {@JoinColumn(name="contact_list_id", updatable = false, insertable = false)}) protected Set<Long> userIncludedItemsIds = Collections.unmodifiableSet(new HashSet<>());
不过这种方法不如@Immutable可靠,因为如果代码中不小心修改了集合(比如反射或者绕过不可修改包装),Hibernate仍可能尝试同步,所以优先推荐第一种方法。
内容的提问来源于stack exchange,提问作者roma2341
相关产品推荐
相关产品推荐

