10

How can I map an array of Doubles in JPA. I have the following code which fails because hibernate cannot initialise the array.

@Entity
public class YearlyTarget extends GenericModel {

    @Id
    public Integer  year;

    @ElementCollection
    public Double[] values;

    public YearlyTarget(int year) {
        this.year = year;
        this.values = new Double[12];
    }
}
emt14
  • 4,676
  • 7
  • 33
  • 57

3 Answers3

12

JPA does not mandate being able to persist arrays to a separate table; obviously JDO does but then you have chosen not to use that. Consequently you need to either store them as @Lob, or change your java type to a List.

DataNucleus
  • 15,199
  • 3
  • 30
  • 37
9

Use an Object type, such as ArrayList. Example

@ElementCollection
public ArrayList<Double> values;

public YearlyTarget(int year) {
    this.year = year;
    this.values = new ArrayList<Double>(12);
}
Codemwnci
  • 51,224
  • 10
  • 90
  • 127
  • Do you mean that arrays cannot be mapped directly with jpa and a collection needs to be used instead? – emt14 Jan 16 '12 at 07:14
  • @emt14 Plain arrays would be a real pain in the ass to work with, if you have a collection of values that changes frequently. [This question](http://stackoverflow.com/questions/4332467/mapping-array-with-hibernate) tackles the same issue, with the same outcome: use a collection. – tmbrggmn Jan 16 '12 at 07:25
  • 1
    Arrays are also the best storage option for a fixed length data type. No overhead compared to collections. Using the collection seems to be a workaround the fact that jpa does not persists arrays. – emt14 Jan 16 '12 at 07:30
  • 2
    @emt14 I suspect JPA implementations can no proxy arrays as easily as lists or other collections. – ewernli Jan 16 '12 at 08:51
  • @emt14 An ArrayList uses an array as underlying storage.There is not that much overhead when using an ArrayList instead of an array. Yes, resizing occurs but usually it does not have a huge performance impact (depends on the context of course). See also: https://stackoverflow.com/questions/716597/array-or-list-in-java-which-is-faster The common opinion is that the benefits of using the List interface abstraction for readability and testability outweighs other concerns. – Adriaan Koster May 17 '19 at 09:15
1

You don't specify the required database structure backing your mapping. @ElementCollection relies on a table that is joined up on retrieving the collection.

In Postgresql database for example you are able to store a simple array in within a column which is possible to map. You will need to in include a dependency:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
</dependency>

And your entity definition will look like:

@Entity
@Table(name = "products")
@TypeDefs(@TypeDef(name = "string-array", typeClass = StringArrayType.class))
public class Product {

    @Type(type = "string-array" )
    @Column(name = "colours")
    private String[] colours;

}

Currently the library only supports ints and strings, but it is a fairly simple task to add new types.

Tian Na
  • 708
  • 2
  • 12
  • 28