Home > front end >  JPA 2 Entity with composite key generates extra redundant *_KEY field in databse
JPA 2 Entity with composite key generates extra redundant *_KEY field in databse

Time:05-30

I'm rewriting some XML configurations to entity classes and I'm experiencing problems with hibernate generated tables.

This is my original XML config for this relation:

<map name="rates" table="article_rate" cascade="all,delete-orphan" lazy="false">
    <key column="fk_article_uuid" foreign-key="article_rate_article_uuid_fk"/>
     <composite-map-key >
        <key-property column="bean_uuid" name="beanUuid" type="UuidType"/>
        <key-property column="rate_type" name="rateType"/>
    </composite-map-key>
    <composite-element >
        <property column="outcome" name="outcome" type="integer"/>
        <property name="value" type="float" precision="17" scale="8">
            <column name="value" sql-type="numeric(17, 8)"/>
        </property>
        <property column="creator_uuid" name="creatorUuid" type="UuidType"/>
        <property column="created" name="created" type="timestamp"/>
    </composite-element>
</map>

After strugling with @ElementCollection and composite primary keys I ended up with 2 entities in relation like this:

@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "article")
@ToString(callSuper = true, onlyExplicitlyIncluded = true)
public class EArticle implements Serializable {
    ... 
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "fk_article_uuid",referencedColumnName = "uuid", nullable = false)
    @MapKeyJoinColumns(value = {@MapKeyJoinColumn(name="bean_uuid"),@MapKeyJoinColumn(name="rate_type")})
    private Map<EArticleRate.Id, EArticleRate> rates = new HashMap<>();
    ...
}

and

@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name="article_rate")
@IdClass(EArticleRate.Id.class)
public class EArticleRate implements Serializable {

    @Getter
    @Setter
    @EqualsAndHashCode(onlyExplicitlyIncluded = true)
    public static class Id implements Serializable {

        @EqualsAndHashCode.Include
        private UUID article;
        @EqualsAndHashCode.Include
        private UUID beanUuid;
        @EqualsAndHashCode.Include
        private String rateType;

        public Id(UUID article, UUID beanUuid, String rateType) {
            this.article = article;
            this.beanUuid = beanUuid;
            this.rateType = rateType;
        }
    }

@javax.persistence.Id
@Column(name = "bean_uuid", nullable = false)
private UUID beanUuid;

@javax.persistence.Id
@Column(name = "rate_type", nullable = false)
private String rateType;

@ManyToOne
@javax.persistence.Id
@JoinColumn(name = "fk_article_uuid", foreignKey = @ForeignKey(name = "article_rate_article_uuid_fk"), insertable = false, updatable = false, nullable = false)
private EArticle article;

@Column(name = "outcome")
private Integer outcome;

@Column(name = "value")
private Float value;

@Column(name = "creator_uuid")
private UUID creatorUuid;

@Column(name = "updated")
private ZonedDateTime modified;

}

hibernate generates table that looks like:

Hibernate: 

create table article_rate (
   fk_article_uuid uuid not null,
    bean_uuid uuid not null,
    rate_type varchar(255) not null,
    creator_uuid uuid,
    updated timestamp,
    outcome int4,
    value float4,
    rates_KEY bytea,
    primary key (fk_article_uuid, bean_uuid, rate_type)
)

While the table itself looks like it's supposed to, the problem is that hibernamte generates it with redundant field rates_KEY bytea and I don't know why. Is there anything wrong with my relation, is it too complicated, can something be simplified?

Any help appreciated.

Regards
Armando
PS: as seen I also use lombok to simplify code.

CodePudding user response:

I've fixed it by remoivng ArticleRate.Id from ArticleRate and changed

Map<ArticleRate.Id, ArticleRate> 

in Article entity to

Set<ArticleRate> 

since I don't need map anymore.

But would still like to know why is hibernate creating redundant field.

CodePudding user response:

Your @OneToMany setup is a bit weird - generally for bidirectional relationship one side (@ManyToOne) does joinColumn to specify it's the owner of the relationship and has the column, while the other side uses mappedBy parameter on @OneToMany annotation. It's likely that not finding it hibernate assumed that the actual foreign key column was not specified and so it generated it from the field name (hence rates_KEY). It also possibly created a fk_article_uuid column in your article table, which you don't need.

  • Related