集合中的Grails域类

Aku*_*ete 7 grails groovy domain-object

集合中使用域对象或在地图中使用键是不好的做法?

在过去,我做过很多这样的事情

Set<Book> someBooks = [] as Set
someBooks.addAll (Book.findAllByAuthorLike('%hofstadter%'))
someBooks.add (Book.findByTitleLike ('%eternal%'))
Run Code Online (Sandbox Code Playgroud)

但是我注意到,在findAllByAuthorLike返回Hibernate Proxy对象列表时会经常遇到问题com.me.Book_$$_javassist_128findByTitleLike会返回正确的com.me.Book对象.这会导致集合中的重复,因为真实对象和代理被认为相等.

我发现在使用像这样的域对象集时我需要非常小心,我觉得它可能是我不应该首先做的事情.

替代方案当然是使用id的集合/映射,但它使我的代码冗长并容易产生误解

Set<Integer> someBooks = [] as Set // a set of id's for books    
Run Code Online (Sandbox Code Playgroud)

@Burt:我认为Grails域类已经这样做了,至少使得equals/compare在class/id而不是对象实例上完成.你的意思是hibernate代理的特殊比较器?

return (this.class == obj.class && this.id == obj.id) || 
       (obj.class  == someHibernateProxy && this.id == obj.id)
Run Code Online (Sandbox Code Playgroud)

Bur*_*ith 9

这不是不好的做法在所有,但就像你应该忽略非Grails应用程序equals以及hashCode如果你将他们将在基于散列的集合(HashSet,HashMap,等),也实现Comparable(这意味着一个compareTo方法),如果你"重新使用TreeSet/ TreeMap/等.

  • 试试吧:) Hibernate代理拦截除getId()之外的所有方法,并确保加载实例.所以equals/hashCode可以正常工作,因为它们将在懒惰加载的真实域类实例上调用. (2认同)