2009-10-01 3 views
11

Estoy buscando lo que la mayoría de la gente usa como su tipo de colección al hacer asociaciones uno a muchos en Hibernate. La aplicación heredada que mantengo usa bolsas exclusivamente, pero las mantiene como listas en código. Las tablas asociadas tienen un campo de identificación, por lo que una bolsa de identificación parece ser más apropiada, pero la documentación recomienda un conjunto.Hibernate: el mejor tipo de colección para usar - bolsa, idbag, conjunto, lista, mapa

EDITAR: Me refirió erróneamente que la documentación recomienda un conjunto. En realidad, la documentación oficial es igualmente vaga en todos los tipos de colección. Lo que me parece es que somewebsites parece inferir que Set es el más común, y el libro que estoy leyendo Hibernate explícitamente dice esto acerca de los conjuntos:

Esta es la colección permanente más común en una aplicación típica de Hibernate. (ver: página 242 de 'Java Persistence with Hibernate' por Christian Bauer y Gavin King)

Supongo que eso es lo que me hizo saltar y me hizo buscar lo que otros están usando.

Edit2: tenga en cuenta que Gavin King es el creador de Hibernate

+0

Tenía la impresión de que se recomendaban conjuntos o algo así porque la herramienta de ingeniería inversa de Hibernate creó mis objetos de dominio POJO utilizando conjuntos casi exclusivamente. – Marvo

Respuesta

9

Ok, después de bastante tiempo he encontrado una razón para NO usar un conjunto como un tipo de colección. Debido a problemas con las anulaciones de hashcode/equals y la forma en que hibernate persiste, el uso de cualquier funcionalidad de java API que invoque hashcode/equals es una mala idea. No hay una buena manera de comparar consistentemente los objetos antes y después de la persistencia. Quédese con las colecciones que no se basan en equal/hashcode como bag.

Más información aquí:

http://community.jboss.org/wiki/EqualsandHashCode (este enlace hace que suene como una clave de negocio es el camino a seguir, pero lee el siguiente enlace completo para ver por qué esto no es siempre una buena idea)

https://forum.hibernate.org/viewtopic.php?f=1&t=928172 (lea toda la discusión para hacer girar la cabeza)

5

supongo personas utilizan todo tipo de cosas :-) - diferentes tipos de colecciones sirven para diferentes propósitos por lo que el "mejor" uno depende de lo que necesita esto para.

Dicho esto, utilizar List en el código es generalmente más conveniente que usar Set aunque dicho List está desordenado. Si nada más, '.get (0)' es más fácil para los ojos que .iterator().next() :-) El soporte de bolsa de Hibernate es definitivamente adecuado para este propósito, además puede incluso agregar una declaración order-by (si corresponde) y tener su lista ordenada.

idbag es un animal completamente diferente utilizado para asociaciones de muchos a muchos; realmente no se puede comparar con Set o List regular.

+1

ChssPly76 dijo: "usar List en el código suele ser más conveniente que usar Set incluso si dicha lista no está ordenada. Si nada más, '.get (0)' es más fácil para los ojos que .iterator(). Next()" - Estoy de acuerdo con esto, que es lo que me lanzó cuando toda la documentación recomienda Conjuntos. Solo quiero ver lo que otras personas están usando y si va en contra de la documentación. Gracias. – Nemi

+0

Sigues diciendo "la documentación recomienda conjuntos". ¿Puedes proporcionar un enlace específico? No creo que la documentación de Hibernate recomiende un tipo de colección sobre otra (¿cómo podría?); simplemente describe varias asignaciones disponibles. No hay una sola palabra "recomendar" en el capítulo sobre colecciones: http://docs.jboss.org/hibernate/stable/core/reference/en/html/collections.html – ChssPly76

+0

@ ChssPly76 - está en lo cierto, por supuesto . Por favor, mira mi edición de arriba. – Nemi

2

Recomendaría utilizar un conjunto porque un conjunto se define como una colección de elementos únicos y eso es normalmente lo que usted trata.

Y .iterator().next() se guarda cuando no hay ningún elemento en su colección.

.get(0) podría lanzar IndexOutOfBoundsException si accede a una lista vacía.

+7

Riiiiight ... ¿Te atreves a probarlo? 'iterator(). hasNext()' es seguro; 'iterator(). next()' ciertamente no lo es. – ChssPly76

+1

Por supuesto, usted comprobaría que al usar los iteradores tiene el método Next, pero nunca se sabe en qué posición se encuentra un elemento en una lista. – MrWhite

+2

También puede comprobar si la lista está vacía (mediante 'isEmpty()', que es, de nuevo, más legible). No estoy seguro de a qué te refieres con "qué posición", dado que comparas List con Set, tu Lista no está ordenada de todos modos. – ChssPly76

12

Basado en la experiencia de usar ambos recomendaría utilizar una lista. Si está sacando datos de la base de datos y mostrándolos/manipulándolos, casi siempre es necesario mantenerlos en un orden constante.Puede usar SortedSet, pero eso puede agregar un mundo de dolor (anulando equals, hashcode, etc. y clasificándolo de diferentes formas) en comparación con solo agregar un pedido y almacenarlo en una lista. Las listas son más fáciles de manipular: si un usuario elimina la línea 3 en la página, simplemente elimine el elemento 3 en la Lista. Trabajar con un conjunto parece implicar un montón de código innecesario y jugar con iteradores.

Cuando he usado Conjuntos con Hibernate, con frecuencia me he encontrado ripeando todos los conjuntos después de algunas semanas y reemplazando con listas porque los conjuntos me están dando demasiadas limitaciones.

La documentación de Hibernate y las herramientas de terceros parecen usar Conjuntos por defecto pero a partir de la experiencia dura, me ha resultado mucho más productivo usar Listas.

Cuestiones relacionadas