persistence icon indicating copy to clipboard operation
persistence copied to clipboard

support SQL arrays

Open gavinking opened this issue 1 year ago • 8 comments

Both Hibernate and EclipseLink have an @Array annotation for mapping Java arrays to SQL array types.

I therefore think we should add the following annotation to JPA:

@Target({FIELD, METHOD})
@Retention( RUNTIME )
public @interface Array {
    /**
     * The maximum length of the array.
     */
    int length();
}

You could use it like this:

@Array(length=10)
String[] tags;

gavinking avatar Sep 20 '24 07:09 gavinking

IMO we should leave fetch and optional to @Basic. Also, the length should maybe be optional with a reasonable default that allows vendor flexibility i.e. value 0.

beikov avatar Sep 20 '24 07:09 beikov

IMO we should leave fetch and optional to @Basic.

Ah yes, you're right. For some reason I thought that @Lob and @Enumerated worked this way. But I misremembered. We should be consistent with those annotations, and let this combine with @Basic.

Also, the length should maybe be optional with a reasonable default that allows vendor flexibility

That sounds like a recipe for unnecessary lack of portability to me.

gavinking avatar Sep 20 '24 07:09 gavinking

That sounds like a recipe for unnecessary lack of portability to me.

I mean, unless you want to actually specify what the default is. But I have no intuition as to what would be a sensible default here.

gavinking avatar Sep 20 '24 08:09 gavinking

The default could be the maximum possible size a DB allows. Since Oracle requires to specify array sizes, but other databases support just "unlimited" (within the bounds of row format limits) elements, a default to max might be nice. If Oracle users care about row size and perf (not sure if the max size affects that), they can specify a lower value.

beikov avatar Sep 20 '24 08:09 beikov

The default could be the maximum possible size a DB allows.

Wouldn't that be extremely inefficient for small arrays?

gavinking avatar Sep 20 '24 08:09 gavinking

Like I wrote, every DB other than Oracle supports unlimited size by default or doesn't even allow specifying a size limit in the column definition. To restrict the size, we'd have to emit a check constraint. I don't know if it is inefficient on Oracle to ask for an array of e.g. 10000 when only storing 1 element, but like I wrote, if users target Oracle, they will want to define that length anyway.

beikov avatar Sep 20 '24 08:09 beikov

If I use this on a raw Collection, I need something like targetEntity, like in ie @OneToMany(targetEntity=...)

lukasj avatar Sep 20 '24 08:09 lukasj

Yeah, Class<?> targetClass() default void.class; is probably appropriate.

beikov avatar Sep 20 '24 08:09 beikov