JPA (Hibernate) 使用 n:m 关联生成错误的查询
JPA (Hibernate) generates wrong query using n:m association
我有一个预定义的 oracle-db,我正在尝试映射下表:
交易系列:
REF_TRADING_SERIES
(
TRADING_SERIES_ID NUMBER(15),
// other attributes
)
交易时段:
REF_TRADING_SESSION
(
TRADING_SESSION_ID NUMBER(15),
// other attributes
)
n:m 协会 TradingComposition:
REF_TRADING_COMPOSITION
(
TRADING_SERIES_ID NUMBER(15),
TRADING_SESSION_ID NUMBER(15),
ITS DATE,
UTS DATE
)
我对应的映射-类:
TradingSeries.class:
@Entity
@Table(name = "REF_TRADING_SERIES", schema = "XXX")
@Cacheable
public class TradingSeries implements java.io.Serializable {
private static final long serialVersionUID = 1482491978920606855L;
private long tradingSeriesId;
// other attributes
private List<TradingComposition> tradingComposition = new ArrayList<TradingComposition>(0);
@Id
@Column(name = "TRADING_SERIES_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long getTradeSessionId() {
return this.tradingSeriesId;
}
@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSeriesId")
public List<TradingComposition> getTradingComposition() {
return tradingComposition;
}
TradingSession.class:
@Entity
@Table(name = "REF_TRADING_SESSION", schema = "XXX")
public class TradingSession implements java.io.Serializable {
private static final long serialVersionUID = 9142731522041102660L;
private long tradingSessionId;
// other attributes
private List<TradingComposition> tradingComposition = new ArrayList<TradingComposition>(0);
@Id
@Column(name = "TRADING_SESSION_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long gettradingSessionId() {
return this.tradingSessionId;
}
@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSessionId")
public List<TradingComposition> getTradingComposition() {
return tradingComposition;
}
TradingComposition.class:
@Entity
@Table(name = "REF_TRADING_COMPOSITION", schema = "XXX")
public class TradingComposition implements java.io.Serializable {
private static final long serialVersionUID = 9142731522041102660L;
@EmbeddedId
private TradingCompositionId tradingCompositionId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ITS", length = 7)
private Date its;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "UTS", length = 7)
private Date uts;
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SERIES_ID")
private TradingSeries tradingSeries;
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SESSION_ID")
private TradingSession tradingSession;
TradingCompositionId.class:
@Embeddable
public class TradingCompositionId implements Serializable {
private static final long serialVersionUID = -1546345156448039243L;
@Column(name = "TRADING_SERIES_ID", nullable = false, precision = 15, scale = 0)
private long tradingSeriesId;
@Column(name = "TRADING_SESSION_ID", nullable = false, precision = 15, scale = 0)
private long tradingSessionId;
现在,当我尝试加载 TradingSeries 时,Hibernate 会执行以下查询:
SELECT tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_64_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_63_0_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID2_63_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_63_1_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID2_63_1_,
tradingcom0_.ITS AS ITS3_63_1_,
tradingcom0_.tradingSeries_TRADING_SERIES_ID
AS tradingSeries_TRAD5_63_1_,
tradingcom0_.tradingSession_TRADING_SESSION_ID
AS tradingSession_TRA6_63_1_,
tradingcom0_.UTS AS UTS4_63_1_,
tradingser1_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_64_2_,
-- other attributes
tradingses2_.TRADING_SESSION_ID AS TRADING_SESSION_ID1_65_3_,
-- other attributes
FROM XXX.REF_TRADING_COMPOSITION tradingcom0_
LEFT OUTER JOIN
XXX.REF_TRADING_SERIES tradingser1_
ON tradingcom0_.tradingSeries_TRADING_SERIES_ID =
tradingser1_.TRADING_SERIES_ID
LEFT OUTER JOIN
XXX.REF_TRADING_SESSION tradingses2_
ON tradingcom0_.tradingSession_TRADING_SESSION_ID =
tradingses2_.TRADING_SESSION_ID
WHERE tradingcom0_.TRADING_SERIES_ID = ?
结果是ORA-00972: identifier is too long
,问题是生成的tradingcom0_.tradingSession_TRADING_SESSION_ID
。这包含错误的字符串 tradingSession_
。当然 tradingcom0_.tradingSeries_TRADING_SERIES_ID
也是不正确的。另外我想知道为什么 hibernate 多次选择相同的字段(在查询的第一行中看到)。
谁能建议我如何解决这个问题?为什么休眠使用了错误的列名?
干杯,
菲利普
找到解决方案:
摆脱了
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SERIES_ID")
private TradingSeries tradingSeries;
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SESSION_ID")
private TradingSession tradingSession;
在TradingComposition.class。 PrimaryKeyJoinColumn 是一个非常糟糕的主意,这里不需要。而是将 TradingCompositionId.class 更改为:
@ManyToOne
@JoinColumn(name = "TRADING_SERIES_ID", nullable = false)
private TradingSeries tradingSeries;
@ManyToOne
@JoinColumn(name = "TRADING_SESSION_ID", nullable = false)
private TradingSession tradingSession;
并删除 long
-属性 tradingsSeriesId
和 tradingSessionId
。
在TradingSeries.class和TradingSession.class中分别将注解改为@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSeries")
@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSession")
.
所有这些更改导致以下 SQL:
SELECT tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID4_64_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID4_63_0_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID3_63_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID4_63_1_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID3_63_1_,
tradingcom0_.ITS AS ITS1_63_1_,
tradingcom0_.UTS AS UTS2_63_1_,
tradingser1_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_64_2_,
-- other attributes
tradingses2_.TRADING_SESSION_ID AS TRADING_SESSION_ID1_65_3_,
-- other attributes
FROM XXX.REF_TRADING_COMPOSITION tradingcom0_
LEFT OUTER JOIN
XXX.REF_TRADING_SERIES tradingser1_
ON tradingcom0_.TRADING_SERIES_ID =
tradingser1_.TRADING_SERIES_ID
LEFT OUTER JOIN
XXX.REF_TRADING_SESSION tradingses2_
ON tradingcom0_.TRADING_SESSION_ID =
tradingses2_.TRADING_SESSION_ID
WHERE tradingcom0_.TRADING_SERIES_ID = ?
我仍然不知道为什么hibernate 为属性TRADING_SERIES_ID 和TRADING_SESSION_ID 添加了多重选择...
我有一个预定义的 oracle-db,我正在尝试映射下表:
交易系列:
REF_TRADING_SERIES
(
TRADING_SERIES_ID NUMBER(15),
// other attributes
)
交易时段:
REF_TRADING_SESSION
(
TRADING_SESSION_ID NUMBER(15),
// other attributes
)
n:m 协会 TradingComposition:
REF_TRADING_COMPOSITION
(
TRADING_SERIES_ID NUMBER(15),
TRADING_SESSION_ID NUMBER(15),
ITS DATE,
UTS DATE
)
我对应的映射-类:
TradingSeries.class:
@Entity
@Table(name = "REF_TRADING_SERIES", schema = "XXX")
@Cacheable
public class TradingSeries implements java.io.Serializable {
private static final long serialVersionUID = 1482491978920606855L;
private long tradingSeriesId;
// other attributes
private List<TradingComposition> tradingComposition = new ArrayList<TradingComposition>(0);
@Id
@Column(name = "TRADING_SERIES_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long getTradeSessionId() {
return this.tradingSeriesId;
}
@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSeriesId")
public List<TradingComposition> getTradingComposition() {
return tradingComposition;
}
TradingSession.class:
@Entity
@Table(name = "REF_TRADING_SESSION", schema = "XXX")
public class TradingSession implements java.io.Serializable {
private static final long serialVersionUID = 9142731522041102660L;
private long tradingSessionId;
// other attributes
private List<TradingComposition> tradingComposition = new ArrayList<TradingComposition>(0);
@Id
@Column(name = "TRADING_SESSION_ID", unique = true, nullable = false, precision = 15, scale = 0)
public long gettradingSessionId() {
return this.tradingSessionId;
}
@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSessionId")
public List<TradingComposition> getTradingComposition() {
return tradingComposition;
}
TradingComposition.class:
@Entity
@Table(name = "REF_TRADING_COMPOSITION", schema = "XXX")
public class TradingComposition implements java.io.Serializable {
private static final long serialVersionUID = 9142731522041102660L;
@EmbeddedId
private TradingCompositionId tradingCompositionId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ITS", length = 7)
private Date its;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "UTS", length = 7)
private Date uts;
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SERIES_ID")
private TradingSeries tradingSeries;
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SESSION_ID")
private TradingSession tradingSession;
TradingCompositionId.class:
@Embeddable
public class TradingCompositionId implements Serializable {
private static final long serialVersionUID = -1546345156448039243L;
@Column(name = "TRADING_SERIES_ID", nullable = false, precision = 15, scale = 0)
private long tradingSeriesId;
@Column(name = "TRADING_SESSION_ID", nullable = false, precision = 15, scale = 0)
private long tradingSessionId;
现在,当我尝试加载 TradingSeries 时,Hibernate 会执行以下查询:
SELECT tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_64_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_63_0_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID2_63_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_63_1_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID2_63_1_,
tradingcom0_.ITS AS ITS3_63_1_,
tradingcom0_.tradingSeries_TRADING_SERIES_ID
AS tradingSeries_TRAD5_63_1_,
tradingcom0_.tradingSession_TRADING_SESSION_ID
AS tradingSession_TRA6_63_1_,
tradingcom0_.UTS AS UTS4_63_1_,
tradingser1_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_64_2_,
-- other attributes
tradingses2_.TRADING_SESSION_ID AS TRADING_SESSION_ID1_65_3_,
-- other attributes
FROM XXX.REF_TRADING_COMPOSITION tradingcom0_
LEFT OUTER JOIN
XXX.REF_TRADING_SERIES tradingser1_
ON tradingcom0_.tradingSeries_TRADING_SERIES_ID =
tradingser1_.TRADING_SERIES_ID
LEFT OUTER JOIN
XXX.REF_TRADING_SESSION tradingses2_
ON tradingcom0_.tradingSession_TRADING_SESSION_ID =
tradingses2_.TRADING_SESSION_ID
WHERE tradingcom0_.TRADING_SERIES_ID = ?
结果是ORA-00972: identifier is too long
,问题是生成的tradingcom0_.tradingSession_TRADING_SESSION_ID
。这包含错误的字符串 tradingSession_
。当然 tradingcom0_.tradingSeries_TRADING_SERIES_ID
也是不正确的。另外我想知道为什么 hibernate 多次选择相同的字段(在查询的第一行中看到)。
谁能建议我如何解决这个问题?为什么休眠使用了错误的列名?
干杯, 菲利普
找到解决方案:
摆脱了
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SERIES_ID")
private TradingSeries tradingSeries;
@ManyToOne
@PrimaryKeyJoinColumn(name = "TRADING_SESSION_ID")
private TradingSession tradingSession;
在TradingComposition.class。 PrimaryKeyJoinColumn 是一个非常糟糕的主意,这里不需要。而是将 TradingCompositionId.class 更改为:
@ManyToOne
@JoinColumn(name = "TRADING_SERIES_ID", nullable = false)
private TradingSeries tradingSeries;
@ManyToOne
@JoinColumn(name = "TRADING_SESSION_ID", nullable = false)
private TradingSession tradingSession;
并删除 long
-属性 tradingsSeriesId
和 tradingSessionId
。
在TradingSeries.class和TradingSession.class中分别将注解改为@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSeries")
@OneToMany(fetch = FetchType.EAGER, mappedBy = "tradingCompositionId.tradingSession")
.
所有这些更改导致以下 SQL:
SELECT tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID4_64_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID4_63_0_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID3_63_0_,
tradingcom0_.TRADING_SERIES_ID AS TRADING_SERIES_ID4_63_1_,
tradingcom0_.TRADING_SESSION_ID AS TRADING_SESSION_ID3_63_1_,
tradingcom0_.ITS AS ITS1_63_1_,
tradingcom0_.UTS AS UTS2_63_1_,
tradingser1_.TRADING_SERIES_ID AS TRADING_SERIES_ID1_64_2_,
-- other attributes
tradingses2_.TRADING_SESSION_ID AS TRADING_SESSION_ID1_65_3_,
-- other attributes
FROM XXX.REF_TRADING_COMPOSITION tradingcom0_
LEFT OUTER JOIN
XXX.REF_TRADING_SERIES tradingser1_
ON tradingcom0_.TRADING_SERIES_ID =
tradingser1_.TRADING_SERIES_ID
LEFT OUTER JOIN
XXX.REF_TRADING_SESSION tradingses2_
ON tradingcom0_.TRADING_SESSION_ID =
tradingses2_.TRADING_SESSION_ID
WHERE tradingcom0_.TRADING_SERIES_ID = ?
我仍然不知道为什么hibernate 为属性TRADING_SERIES_ID 和TRADING_SESSION_ID 添加了多重选择...