38

With JPA annoations, I want to reuse same embedded object like this :

@Entity
public class User {
    @Embedded
    public Address homeAddress;

    @Embedded
    public Address workAddress;
}

@Embeddable
public class Address {
    public String code;
    public String city;
    ...
} 

I can specify SQL column names with @AttributeOverrides, @AttributeOverride and @Column, but it's verbos. Is it possible to specify just a prefix to add to each column for homeAddress and workAddress ?

Thanks,

Xavier

xnopre
  • 583
  • 1
  • 4
  • 10
  • possible duplicate of [JPA Multiple Embedded fields](http://stackoverflow.com/questions/331744/jpa-multiple-embedded-fields) – Adrian Ber Feb 03 '15 at 13:25

3 Answers3

16

If you would like to use multiple same Embedded class. You have to do @AttributeOverrides for all columns. Try as below;

Reference JPA AttributeOverrides

@Embeddable
public class Address {
    private String state;
    @Column(name = "zip_code")
    private String zip;
}

@Entity(name = "Employee")
public class Employee implements Serializable {
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "state", column = @Column(name = "province_1")),                       
        @AttributeOverride(name = "zip", column = @Column(name = "postal_code_2"))
    })
    private Address address_1;  

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "state", column = @Column(name = "province_2")),                       
        @AttributeOverride(name = "zip", column = @Column(name = "postal_code_2"))
    })
    private Address address_2;  

}   

My suggestion, if there are one or more Embedded value in your Entity. Try to use @CollectionTable.

@CollectionTable(name = "EMPLOYEE_ADDRESS", joinColumns = @JoinColumn(name = "ADDRESS_ID"))
private List<Address> addressList;

Reference JPA CollectionTable

Zaw Than oo
  • 9,651
  • 13
  • 83
  • 131
  • 23
    Thanks, I know this solution, but it's verbose. Is there any solution to be less verbose, like using something like "prefix" or "suffixe" ("_1" or "_2" in your example) ? – xnopre Oct 17 '12 at 14:17
  • For any Groovy users trying the above and getting a compile error, the solution is to substitute the { } with [ ] within the @AttributesOverrides annotation. – zwessels Jan 05 '17 at 21:05
4

adding this works for me (i'm using hibernate as JPA provider though)

<property name="hibernate.implicit_naming_strategy" value="org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl" />
Mahes
  • 3,938
  • 1
  • 34
  • 39
  • 5
    in spring boot (2.3.6) this is: `spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl` – elonderin Jun 17 '21 at 04:52
1

In 2022 (after 9 Years) @zaw-than-oo -s answer is still valid :-( .

This "Duplicate" answer is for reference if sombody wants to improve jpa-embedded.

Here is a working crossplatform example based on @zaw-than-oo -s answer with verbose java-jpa and easy to use android-room

@androidx.room.Entity
@javax.persistence.Entity
@javax.persistence.Inheritance(strategy = javax.persistence.InheritanceType.SINGLE_TABLE)
public class AppHardware {
    @javax.persistence.Id
    @javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
    @androidx.room.PrimaryKey(autoGenerate = true)
    private int id;

    // max is embedded without column renaming
    @androidx.room.Embedded
    @javax.persistence.Embedded
    private ProfileCommon max;

    // min is embedded with column renaming
    @androidx.room.Embedded(prefix = "min")
    @javax.persistence.Embedded
    @javax.persistence.AttributeOverrides({
        // Verbose: every persisted property in ProfileCommon needs an entry
        // see https://stackoverflow.com/questions/12912063/jpa-multiple-embedded-fields-with-prefix
        @AttributeOverride(name = "added", column = @Column(name = "minadded")),
        @AttributeOverride(name = "apkName", column = @Column(name = "minapkName")),
        @AttributeOverride(name = "versionCode", column = @Column(name = "minversionCode")),
        @AttributeOverride(name = "versionName", column = @Column(name = "minversionName")),
        @AttributeOverride(name = "size", column = @Column(name = "minsize"))
        
    })
    private ProfileCommon min;

    // getter and setter onmitted
}

@javax.persistence.MappedSuperclass
public class ProfileCommon  {
    private long added; // date
    private String apkName;
    private long versionCode;
    private String versionName;
    private long size;

// getter and setter onmitted
}
k3b
  • 14,517
  • 7
  • 53
  • 85