Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically order many-to-many relationship with JPA or HQL?

I have a mapping like this:

@ManyToMany(cascade = CascadeType.PERSIST)
    @JoinTable(
            name="product_product_catalog",
            joinColumns={@JoinColumn(name="product_catalog", referencedColumnName="product_catalog")},
            inverseJoinColumns={@JoinColumn(name="product", referencedColumnName="product")})
    public List<Product> products = new ArrayList<Product>();

I can fetch the products for the catalog nicely, but I can't (dynamically) order the products. How could I order them? I probably have to write a many-to-many HQL query with the order-by clause? I though of passing the orderBy field name string to the query, or is there a better solution?

Tables are: products, product_catalog, product_product_catalog (associative table)

P.S. Using Play! Framework JPASupport for my entities.

like image 304
Indrek Avatar asked Jun 08 '10 23:06

Indrek


People also ask

How do you persist many-to-many relationships in JPA?

In JPA we use the @ManyToMany annotation to model many-to-many relationships. This type of relationship can be unidirectional or bidirectional: In a unidirectional relationship only one entity in the relationship points the other. In a bidirectional relationship both entities point to each other.

What is dynamic query in JPA?

Queries that are created at runtime by the application are called dynamic queries. Dynamic queries are created when we pass a simple JPA compliant query string to the createQuery method of the EntityManager class.

What is @OrderColumn?

@OrderColumn is used to store list index. As list is ordered collection, so to maintain the list index there can be a column in database and while inserting the data, list index will be stored in that column. For this the property in entity should be annotated with. @OrderColumn (name="column-name")


1 Answers

I can fetch the products for the catalog nicely, but I can't (dynamically) order the products. How could I order them?

Not possible if you let JPA retrieve the association. Mappings are static, the best thing you can do with mappings is to specify the order at "retrieve time":

9.1.28 OrderBy Annotation

The OrderBy annotation specifies the ordering of the elements of a collection valued association at the point when the association is retrieved.

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OrderBy {
   String value() default "";
}

The syntax of the value ordering element is an orderby_list, as follows:

orderby_list::= orderby_item [,orderby_item]*
orderby_item::= property_or_field_name [ASC | DESC]

If ASC or DESC is not specified, ASC (ascending order) is assumed.

If the ordering element is not specified, ordering by the primary key of the associated entity is assumed.

The property or field name must correspond to that of a persistent property or field of the associated class. The properties or fields used in the ordering must correspond to columns for which comparison operators are supported.

Example:

@Entity public class Course {
  ...
  @ManyToMany
  @OrderBy("lastname ASC")
  public List<Student> getStudents() {...};
  ...
}

So either use a custom finder or sort your list from Java using a Comparator.

like image 188
Pascal Thivent Avatar answered Oct 02 '22 07:10

Pascal Thivent