我正在將一些 XML 配置重寫為物體類,并且遇到了休眠生成表的問題。
這是我對這種關系的原始 XML 配置:
<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 class="org.dropchop.jop.beans.ArticleRate$Id">
<key-property column="bean_uuid" name="beanUuid" type="UuidType"/>
<key-property column="rate_type" name="rateType"/>
</composite-map-key>
<composite-element class="org.dropchop.jop.beans.ArticleRate">
<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>
在與@ElementCollection 和復合主鍵苦苦掙扎之后,我最終得到了兩個相關的物體,如下所示:
@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<>();
...
}
和
@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 生成的表如下所示:
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)
)
雖然表本身看起來應該是這樣,但問題是 hibernamte 使用冗余欄位rates_KEY bytea生成它, 我不知道為什么。我的關系有什么問題嗎,是不是太復雜了,可以簡化一下嗎?
任何幫助表示贊賞。
問候
Armando
PS:如所見,我還使用 lombok 來簡化代碼。
uj5u.com熱心網友回復:
我已經通過從 ArticleRate 中洗掉 ArticleRate.Id 并更改了它來修復它
Map<ArticleRate.Id, ArticleRate>
在文章物體中
Set<ArticleRate>
因為我不再需要地圖了。
但是還是想知道為什么hibernate會創建冗余欄位。
uj5u.com熱心網友回復:
您的@OneToMany設定有點奇怪 - 通常對于雙向關系,一側(@ManyToOne)確實 joinColumn 指定它是關系的所有者并擁有列,而另一側使用注釋mappedBy上的引數。@OneToMany很可能沒有找到它休眠假設未指定實際的外鍵列,因此它從欄位名稱生成它(因此rates_KEY)。它還可能fk_article_uuid在您的article表中創建了一個您不需要的列。
uj5u.com熱心網友回復:
在掙扎了一些之后,由于使用 Set 我什至在存盤費率方面遇到了更多問題,我決定回傳原始解決方案并設法使其與 Map 一起使用。
ArticleRate 現在看起來像
@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name="article_rate")
public class EArticleRate implements Serializable {
@Embeddable
public static class RateId implements Serializable {
private UUID beanUuid;
private String rateType;
private UUID articleUuid;
public RateId() {
}
public RateId(UUID beanUuid, String rateType, UUID articleUuid) {
this.beanUuid = beanUuid;
this.rateType = rateType;
this.articleUuid = articleUuid;
}
public UUID getBeanUuid() {
return beanUuid;
}
public void setBeanUuid(UUID beanUuid) {
this.beanUuid = beanUuid;
}
public String getRateType() {
return rateType;
}
public void setRateType(String rateType) {
this.rateType = rateType;
}
public UUID getArticleUuid() {
return articleUuid;
}
public void setArticleUuid(UUID articleUuid) {
this.articleUuid = articleUuid;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RateId rateId = (RateId) o;
return beanUuid.equals(rateId.beanUuid) && rateType.equals(rateId.rateType) && articleUuid.equals(rateId.articleUuid);
}
@Override
public int hashCode() {
return Objects.hash(beanUuid, rateType, articleUuid);
}
}
@EmbeddedId
private RateId id;
@ManyToOne
@MapsId("articleUuid")
@JoinColumn(name = "fk_article_uuid", foreignKey = @ForeignKey(name = "article_rate_article_uuid_fk"), insertable = false, updatable = false, nullable = false)
private EArticle article;
/** other fields **/
}
我的文章物體中的關系現在看起來像:
@OneToMany(mappedBy = "article", fetch = FetchType.EAGER, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, orphanRemoval = true)
@MapKey(name = "id")
private Map<EArticleRate.RateId, EArticleRate> rates = new HashMap<>();
我的文章價格資料庫表現在是正確的,也是我想要的
create table article_rate (
fk_article_uuid uuid not null,
beanUuid uuid not null,
rateType varchar(255) not null,
creator_uuid uuid not null,
updated timestamp,
outcome int4,
value float4,
primary key (fk_article_uuid, beanUuid, rateType)
)
我想使用 map ,因為我通常知道我想用一個鍵得到什么速率,所以我不必使用 .stream() 或迭代來找到正確的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/483670.html
上一篇:entityManagerFactorybean未配置休眠6.0.2.Final和springboot2.7.0的問題
