2010-11-22 9 views
13

¿La hibernación conserva el orden de un LinkedHashSet y, de ser así, cómo? En caso de que esto dependa del tipo de base de datos, me gustaría saberlo para PostgreSQL.¿Hibernate conserva el orden de un LinkedHashSet y, de ser así, cómo?

Antecedentes:

sé qué es para LinkedHashSet, y la razón por la que estoy pidiendo esto se debe a que estoy registrar los nombres de algunas de las funciones que ejecutar para una mesa 'logError' que tiene una relación de muchos a muchos con alguna tabla de 'nombre de función'. Necesito que estas funciones permanezcan en el mismo orden que cuando las ejecuté, así que primero encuentro los objetos correspondientes 'functionName', los pongo en un LinkedHashSet (después de que cada función falló) y luego persisto el objeto 'logError'.

Ahora cuando vuelvo a obtener el objeto 'logError' de la base de datos, ¿todavía se ordenará? Y si es así, tenía curiosidad de cómo Hibernate lo hace.

+1

¿Ha intentado hacer anotaciones con @OrderColumn? (Tal vez eso es una anotación JPA) – willcodejavaforfood

Respuesta

13

Primero: asumo que estás hablando de una relación entre dos entidades. Algo así como

@Entity 
public class A { 
@ManyToMany 
    @JoinTable(name = "A_B", joinColumns = { @JoinColumn(name = "A_fk") }, inverseJoinColumns = { @JoinColumn(name = "B_fk") }) 
    private Set<B> bSet = new LinkedHashSet<B>(); 
} 

Hibernate no conserva el orden por sí mismo!

Si usted tiene un vistazo a las clases que se utilizan cuando la entidad A se carga desde la base de datos, entonces el SetbSet es de tipo PersistentSet, que es una envoltura alrededor de otro Set, y esto es (en mi caso) normal HashSet. (HashSet no conserva el orden de sus elementos.)

Incluso si Hibernate utiliza List o LinkedHashSet, sigue siendo aconsejable basar la aplicación en el orden natural de la base de datos (no garantizado). Para MySQL es algún tipo de antipatrón.

Pero puede usar la anotación @Sort (org.hibernate.annotations.Sort) para hacer su clasificación explícita. Por ejemplo:

@OneToMany(mappedBy = "as") 
@Sort(type = SortType.COMPARATOR, comparator = MyBComparator.class); 
public SortedSet<C> cs; 

@see: Ordering return of Child objects in JPA query


Añadido por Łukasz Rzeszotarski en 1Th Sep 2012:

Pero tenemos que recordar que el uso de @Sort anotación hace que los objetos en la clasificación memoria (jvm) y no en sql. En cambio, podemos usar la anotación @OrderBy que causa la clasificación en el lado del servidor sql. Ambas anotaciones tienen en mi opinión (Łukasz Rzeszotarski) una debilidad que configura el orden por defecto. I (Łukasz Rzeszotarski) preferiría hibernar utiliza su propia implementación LinkedHashSet cuando 've' que se usa la cláusula order by.

@see: Hibernate ordering in sql

+3

@ Łukasz Rzeszotarski: si edita de alguien puesto de nuevo de esta manera, a continuación, hacer al menos claro que esta era su estado de cuenta, y no a los autores originales uno! – Ralph

+0

Esta es la respuesta estúpida si realmente tiene un mapa normal y no respecto entidad y lo que desea es preservar el orden a través de 'LinkedHashMap' – Enerccio

+0

@Enerccio: la pregunta es acerca de cómo hibernación tienda (o no) el orden de un LinkedHashSet, es no se trata de que quieras que almacenen un mapa. Si crees que mi respuesta es incorrecta (tal vez lo sea), por favor escribe una respuesta correcta y yo desviaré la tuya y votaré la tuya. – Ralph

0

Los conjuntos no tienen un 'orden' inherente ni las tablas de la base de datos: puede aplicar un pedido cuando consulta los datos, pero a menos que conserve ese orden (por ejemplo, obteniendo las filas una a una y colocándolas en un orden contenedor como una lista enlazada), entonces los datos devueltos también serán desordenados.

+1

LinkedHashSet tiene orden de inserción – willcodejavaforfood

0

Cuando necesito para conservar el orden de una lista de elementos, uso un Map y no un List.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL) 
@MapKey(name = "position") 
private Map<Integer, RuleAction> actions    = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this })); 

En este Java ejemplo, position es una propiedad de entero de RuleAction lo que el orden se conserva de esa manera. Supongo que en C# esto se vería bastante similar.

Cuestiones relacionadas