简体   繁体   中英

JPA AttributeOverride for Embeddable class with Entity type fields

I have an embeddable class with two fields. One is an enum, and the other field is of an entity class type.

@Embeddable
public class EmbeddableClass {
    @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="myField", insertable = false, updatable = false)
    private EntityClass myField;

    @Enumerated(EnumType.STRING)
    @Column(name="enumValue", insertable=false, updatable=false)
    private EnumClass enumValue;

    protected EmbeddableClass() {}

    public EmbeddableClass(EntityClass myField, EnumClass enumValue) {
        this.myField = myField;
        this.enumValue = enumValue;
    }
}

I'm trying to embed objects of this class in another class. Two fields will be of this type, so I have to use @AttributeOverrides

@Entity
public class MyClass {
    @Column(name = "column_one")
    @AttributeOverrides({
            @AttributeOverride(name="enumValue", column= @Column(name="column_one_enum_value")),
            @AttributeOverride(name="myField", column= @Column(name="column_one_my_field"))
    })
    @Embedded
    private EmbeddableClass embeddableClass1;

    @Column(name = "column_two")
    @AttributeOverrides({
            @AttributeOverride(name="enumValue", column= @Column(name="column_two_enum_value")),
            @AttributeOverride(name="myField", column= @Column(name="column_two_my_field"))
    })
    @Embedded
    private EmbeddableClass embeddableClass2;

    // ...
}

In the database, I am expecting that the MyClass table will have 4 columns named after the second arguments of the @AttributeOverride annotations. But that is not what I get.

The two columns for the enums are correct. But for the entity class fields I don't get two separate columns. I just get one column based on the type name: entity_class . And when I persist MyClass objects into the database, the entity_class column remains null, even though the objects I am persisting do have a myField value.

Is there a way for me to achieve the 4 columns I described above while still keeping the class Embeddable?

You do not have to use @Column annotation for @Embedded objects which should be replaced in the MyClass entity by two columns each.

update I double checked with documentation and it seems the following updates are needed:

  1. Add referencedColumnName = "id" to join column definition in EmbeddableClass
@Embeddable
public class EmbeddableClass {
    @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="myField", referencedColumnName = "id", insertable = false, updatable = false)
    private EntityClass myField;

    @Enumerated(EnumType.STRING)
    @Column(name="enumValue", insertable=false, updatable=false)
    private EnumClass enumValue;

    protected EmbeddableClass() {}

    public EmbeddableClass(EntityClass myField, EnumClass enumValue) {
        this.myField = myField;
        this.enumValue = enumValue;
    }
}
  1. Update name attribute in @AssociationOverride/@AttributeOverride with the reference to instance name embeddableClass1 / embeddableClass2 :
@AssociationOverrides({
    @AssociationOverride(name="embeddableClass1.myField", joinColumns = @JoinColumn(name="column_one_my_field")),
    @AssociationOverride(name="embeddableClass2.myField", joinColumns = @JoinColumn(name="column_two_my_field"))
})
@AttributeOverrides({
    @AttributeOverride(name="embeddableClass1.enumValue", column= @Column(name="column_one_enum_value")),
    @AttributeOverride(name="embeddableClass2.enumValue", column= @Column(name="column_two_enum_value"))
})
@Entity
public class MyClass {
    @Embedded
    private EmbeddableClass embeddableClass1;

    @Embedded
    private EmbeddableClass embeddableClass2;

    // ...
}
  1. (Optional) If you need mappings in EntityClass , you can add them as explained here :
@Entity
public class EntityClass {
    @Id
    private int id;

    @OneToOne(mappedBy = "embeddableClass1.myField")
    private MyClass myClass1;

    @OneToOne(mappedBy = "embeddableClass2.myField")
    private MyClass myClass2;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM