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.