jakartaee / persistence

https://jakartaee.github.io/persistence/
Other
189 stars 55 forks source link

add @EmbeddableResult #470

Open gavinking opened 10 months ago

gavinking commented 10 months ago

Section 3.10.16.1 of the spec specifies that embeddable objects returned by native queries are handled by specifying a property path using the name member of @FieldResult. For example:

@SqlResultSetMapping(name=”CustomerResults”, 
    entities=@EntityResult(entityClass=Customer.class, 
        fields={@FieldResult(name="id", column="customer_id"),
                @FieldResult(name="address.street", column="customer_street"),
                @FieldResult(name="address.city", column="customer_city"),
                @FieldResult(name="address.state", column="customer_state"),
                @FieldResult(name="status", column="customer_status")}
)

This works but somehow I always found it slightly weird, bordering on inelegant, that, given that @Embeddable objects are a basic construct in the type system of JPA, there was no corresponding @EmbeddableResult annotation.

@SqlResultSetMapping(name=”CustomerResults”, 
    entities=@EntityResult(entityClass=Customer.class, 
        fields={@FieldResult(name="id", column="customer_id"),
                @FieldResult(name="status", column="customer_status")},
        embeddables=@EmbeddableResult(name = address,
            fields={@FieldResult(name="street", column="customer_street"),
                    @FieldResult(name="city", column="customer_city"),
                    @FieldResult(name="state", column="customer_state")}))
)

Is that better? Maybe not. We all hate nested annotations in Java!

But in light of #459, this code example can easily be made typesafe, whereas the first cannot:

@SqlResultSetMapping(name=”CustomerResults”, 
    entities=@EntityResult(entityClass=Customer.class, 
        fields={@FieldResult(name=Customer_.ID, column="customer_id"),
                @FieldResult(name=Customer_.STATUS, column="customer_status")},
        embeddables=@EmbeddableResult(name = address,
            fields={@FieldResult(name=Address_.STREET, column="customer_street"),
                    @FieldResult(name=Address_.CITY, column="customer_city"),
                    @FieldResult(name=Address_.STATE, column="customer_state")}))
)

And this is, in my opinion, sufficient reason to add such an annotation to JPA.

gavinking commented 10 months ago

Note that this enhancement is also, IMO, needed in order to do #9 in an elegant way.

gavinking commented 10 months ago

A limitation here, and, perhaps, an argument against doing it all, is that due to Java language limitations, nested @EmbeddableResults would not be allowed. That's annoying.