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-属性 tradingsSeriesIdtradingSessionId。 在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 添加了多重选择...