我有一个grails项目,它抛出以下异常:
org.springframework.dao.DataIntegrityViolationException: could not delete: [Role#4]; SQL [delete from role where id=? an
d version=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not del
ete: [Role#4]
在我的角色域中,我所做的就是创建此错误,是改变其中一个变量的定义
List<RoleTool> roleTools = new ArrayList<RoleTool>()
到
ArrayList<RoleTool> roleTools = new ArrayList<RoleTool>()
为什么?
答案 0 :(得分:1)
通常,在变量声明和方法签名中将具体类指定为声明类型是不好的做法。除非您确实需要它作为ArrayList,否则请将其保留为List以允许更大的灵活性。
我不完全确定这里发生了什么,但是Hibernate有自己的集合类,它用于映射集合,最常用的是org.hibernate.collection.PersistentList
和org.hibernate.collection.PersistentSet
。它们分别实现List和Set接口,但不扩展ArrayList或HashSet或任何典型的具体集合。相反,他们是Hibernate内部类,它们监视更改,以便在持久化,刷新等时帮助进行脏检测。
将初始集合声明为ArrayList是好的,因为它只能在保存时读取(虽然它是Groovy,所以使用List<RoleTool> roleTools = []
会更加清晰)。但是Hibernate在加载持久化实例时需要灵活地实现List / Set接口。