Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate @AttributeOverride columnNames of embedded CompositeType

Tags:

java

hibernate

I have an Amount that is mapped to two database columns via a CompositeUserType:

public class Amount  {
    private BigDecimal value;
    private CurrencyCode currency;
}

It is used in this Embeddable:

@Embeddable
public class AccountBalance {
    private Calendar date;

    @Type(type = Amount.TYPE_DEF)
    @Columns(columns = {
        @Column(name = "amount"),
        @Column(name = "currencyCode")})
    private Amount amount;
}

Which is embedded multiple times here:

public class AccountStatement
    @AttributeOverrides(value = {
        @AttributeOverride(name = "date", column = @Column(name = "openingBalanceDate") ),
        @AttributeOverride(name = "amount.amount", column = @Column(name = "openingBalanceAmount") ),
        @AttributeOverride(name = "amount.currencyCode", column = @Column(name = "openingBalanceCurrency") )})
    @Embedded
    @Basic(optional = true)
    private AccountBalance openingBalance;

    @AttributeOverrides(value = {
        @AttributeOverride(name = "date", column = @Column(name = "closingBalanceDate") ),
        @AttributeOverride(name = "amount.amount", column = @Column(name = "closingBalanceAmount") ),
        @AttributeOverride(name = "amount.currencyCode", column = @Column(name = "closingBalanceCurrency") )})
    @Embedded
    @Basic(optional = true)
    private AccountBalance closingBalance;

Which results in:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: ...AccountStatement column: amount (should be mapped with insert="false" update="false")

When I add updatable = false, insertable = false into the two columns in AccountBalance (as suggested in the exception text), schema validation is successful, but it fails on inserting data, because it tries to insert a BigDecimal into the next field in the PreparedStatement (not shown in my excerpt) which is a date.

So I want the values to be insertable and updatable.

This leads to the conclusion that hibernate does not handle my AttributeOverrides annotation for the two columns of Amount correctly.

I already tried multiple options:

  1. amount.amount and amount.currencyCode (the column names, as in the excerpt)
  2. amount.value and amount.currency (the field names inside Amount and the values returned by getPropertyNames of my CompositeUserType
  3. just amount and currencyCode (results in AnnotationException: AttributeOverride.column() should override all columns for now)

Hibernate does not seem to really care too much what comes after the dot. I can change that to amount.abcdef and it will not throw an error, so I'm pretty much just guessing right now, how to override these column names.

When Amount is not inside an Embeddable it works just fine with this declaration, even when used multiple times in the same entity.

    @Type(type = Amount.TYPE_DEF)
    @Columns(columns = {
        @Column(name = "amount"),
        @Column(name = "currencyCode")})
    private Amount amount;

Does somebody have an idea? All I could find to that topic was only related to Embeddables and not CompositeUserTypes inside Embeddables.

I'm using hibernate-5.1.2-final.

like image 509
Marty Avatar asked Sep 06 '25 02:09

Marty


1 Answers

I've since submitted a pull request to Hibernate, that was merged recently, which will allow this to work: https://hibernate.atlassian.net/browse/HHH-11465

The way this patch works, you will need to specify the same override name twice, so in your example it will be:

@AttributeOverrides(value = {
    @AttributeOverride(name = "date", column = @Column(name = "openingBalanceDate") ),
    @AttributeOverride(name = "amount", column = @Column(name = "openingBalanceAmount") ),
    @AttributeOverride(name = "amount", column = @Column(name = "openingBalanceCurrency") )})
@Embedded
@Basic(optional = true)
private AccountBalance openingBalance;

(The order has to be what it is in the CompositeUserType.)

This is now merged, so it will be released in the next release of Hibernate 5.2, which will be 5.2.11.

like image 56
Kiscsirke Avatar answered Sep 07 '25 16:09

Kiscsirke