ebean icon indicating copy to clipboard operation
ebean copied to clipboard

Ordering column is not maintained by Ebean with @OrderColumn on @ElementCollection

Open vladimirfx opened this issue 4 years ago • 1 comments

Expected behavior

When embedded collection persists column specified in @OrderColumn should be populated in order to maintain collection ordering.

Actual behavior

The column specified in @OrderColumn is not populated at all.

Steps to reproduce

Sample mapping (in Kotlin, sorry):

@Entity
class Order {
  @Id
  val id: Long = 0

  @ElementCollection
  @OrderColumn(name = "ordinal")
  val items: MutableList<OrderItem> = mutableListOf()
}

@Embeddable
data class OrderItem(
  val nomenclatureId: Long,
  val amount: Int,
  val comment: String? = null,
)

Order item schema:


create table order_item
(
	order_id bigint not null primary key,
	ordinal int not null primary key,
	nomenclature_id bigint not null,
        amount int not null,
	comment varchar(200)
);

https://docs.oracle.com/javaee/6/api/javax/persistence/OrderColumn.html

Specifically:

The order column must be of integral type. The persistence provider maintains a contiguous (non-sparse) ordering of the values of the order column when updating the association or element collection. The order column value for the first element is 0.

That works in any compliant JPA provider and we were hit by this on few cases in the migrated projects.

So if it is planned to implement I will provide tests. If not - may I ask for some workaround for this issue?

vladimirfx avatar Sep 23 '21 14:09 vladimirfx

@rbygrave we hit the same problem now, when defining @ElementCollections like

  @ElementCollection
  @CollectionTable(joinColumns = @JoinColumn(name = "person_id"))
  @OrderColumn(name="foo")
  List<EcPhone> phoneNumbers = new ArrayList<>();

We would expect an order by statement. For example in TestElementCollectionEmbeddedList

 assertSql(sql.get(1)).contains("select t0.person_id, t0.country_code, t0.area, t0.phnum from ecbl_person_phone_numbers");
 assertSql(sql.get(1)).contains("order by t0.foo")

rPraml avatar Jan 21 '22 10:01 rPraml