JPA(Hibernate)使用n:m关联生成错误的查询

时间:2015-03-02 11:58:01

标签: java oracle hibernate jpa

我有一个预定义的oracle-db,我正在尝试映射下面的表:

TradingSeries:

REF_TRADING_SERIES
(
    TRADING_SERIES_ID  NUMBER(15),
    // other attributes
)

TradingSession:

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多次选择相同的字段(在查询的第一行中看到)。

有人能建议我如何解决这个问题吗? Ehy是使用错误的列名来休眠的吗?

干杯, 菲利普

1 个答案:

答案 0 :(得分:1)

找到解决方案:

Ged摆脱

@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添加多个选择......