2012-07-10 69 views
5

Im一直存在這個問題。數據庫模式由其他人提供,所以我不能簡單地更改名稱。我嘗試添加適當的註釋,也許我錯過了什麼(明顯)?hibernate oracle標識符太長ORA-00972

這是我的完整映射(相當多classess),我會省略getter/setters。

問題是,當Hibernate是試圖讓所有List<ControlRuleAttrib> controlRuleAttribs

CONTROLE規則

@Entity 
@Table(name = "CONTROL_RULE") 
public class ControlRule implements Serializable { 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "CONTROL_RULE_ID") 
private Long id; 
@ManyToOne(fetch = FetchType.LAZY) 
@Cascade(CascadeType.ALL) 
@JoinColumn(name = "CONTROL_RULE_TYPE_ID") 
@ForeignKey(name = "CONTROL_RULE_TYPE_ID") 
private ControlRuleType controlRuleType; 
@Column(name = "JOB_NM") 
private String jobname; 
@Column(name = "LIBRARY_NM") 
private String libraryname; 
@Column(name = "TABLE_NM") 
private String tablename; 
@Column(name = "COLUMN_NM") 
private String columnname; 

@OneToMany(fetch = FetchType.LAZY) 
@Cascade(CascadeType.ALL) 
@JoinTable(name = "CONTROL_RULE_ATTRIB", joinColumns = { 
    @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false) 
}) 
private List <ControlRuleAttrib> controlRuleAttribs; 
} 

ControlRuleAttrib

@Table(name = "CONTROL_RULE_ATTRIB") 
@Entity 
public class ControlRuleAttrib { 
@EmbeddedId 
private ControlRuleAttribPK controlRuleAttribPK; 

@Column(name = "ATTRIBUTE_VALUE") 
private String attributeValue; 
} 

ControleRuleAttribPK 這裏的問題是,是否有可能從ControlRuleAttrib獲得實體ControlRuleAttribType?正如您在下面看到的ControlRuleAttribTypeIdControleRuleAttribType的編號。我想得到整個對象的整數。

@Embeddable 
public class ControlRuleAttribPK implements Serializable { 
@Column(name = "CONTROL_RULE_ID") 
private Long controlRuleId; 

@Column(name = "ATTRIBUTE_SEQ_NUM") 
private Integer attributeSeqNum; 

@Column(name = "CONTROL_RULE_ATTRIB_TYPE_ID") 
private Integer controlRuleAttribTypeId; 
} 

ControleRuleAttribType

@Entity 
@Table(name = "CONTROL_RULE_ATTRIB_TYPE") 
public class ControlRuleAttribType implements Serializable { 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "CONTROL_RULE_ATTRIB_TYPE_ID") 
private Integer id; 
@Column(name = "CONTROL_RULE_ATTRIB_TYPE_NM") 
private String typename; 
@Column(name = "CONTROL_RULE_ATTRIB_TYPE_DESC") 
private String typedesc; 

@ManyToOne(fetch = FetchType.LAZY) 
@Cascade(CascadeType.ALL) 
@JoinColumn(name = "CONTROL_RULE_TYPE_ID") 
@ForeignKey(name = "CONTROL_RULE_TYPE_ID") 
private ControlRuleType controlruletype; 
} 

ControleRuleType

@Entity 
@Table(name = "CONTROL_RULE_TYPE") 
public class ControlRuleType implements Serializable { 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "CONTROL_RULE_TYPE_ID") 
private Integer id; 
@Column(name = "CONTROL_RULE_TYPE_NM") 
private String typename; 
@Column(name = "CONTROL_RULE_TYPE_DESC") 
private String typedesc; 
} 

EDIT

這裏是堆棧跟蹤:

https://gist.github.com/a30dd9ce534d96bb9a97

正如你會發現,它失敗在這裏:

at com.execon.controllers.main.MainPageController.getMainPage(MainPageController.java:33) [classes:]

,這是它:

List<ControlRule> list = SessionFactoryUtils.openSession(
    sessionFactory).createQuery("from ControlRule").list(); 
System.out.println(list); 

我添加了映射每一個對象,具有toString()方法聲明如下:

@Override 
public String toString() 
{ 
    String s = "ControlRule{"; 
    s += "id=" + id.toString(); 
    s += ", controlRuleType=" + controlRuleType; 
    s += ", jobname='" + jobname + '\''; 
    s += ", libraryname='" + libraryname + '\''; 
    s += ", tablename='" + tablename + '\''; 
    s += ", columnname='" + columnname + '\''; 
    s += ", controlRuleAttribs=" + controlRuleAttribs; 
    s += '}'; 
    return s; 
} 

和Hibernate的要求:

https://gist.github.com/c8584113522757a4e0d8/4f31dc03e7e842eef693fa7ba928e19d27b3ca26

請幫助:)

EDIT 2

閱讀@Jens答案後好了,我做了一些代碼的變化。首先我按照你的寫法做了,它給了錯誤:

org.hibernate.AnnotationException: A Foreign key refering com.execon.models.controlrules.ControlRuleAttrib from com.execon.models.controlrules.ControlRule has the wrong number of column. should be 3

我想這是正確的,因爲我有複合主鍵。

然後我試圖這樣說:

@OneToMany(fetch = FetchType.LAZY) 
@Cascade(CascadeType.ALL) 
@JoinTable(name = "CONTROL_RULE_ATTRIB", 
     joinColumns = { 
       @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false) 
     }, 
     inverseJoinColumns = { 
       @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false), 
       @JoinColumn(name = "CONTROL_RULE_ATTRIB_TYPE_ID", nullable = false, updatable = false), 
       @JoinColumn(name = "ATTRIBUTE_SEQ_NUM", nullable = false, updatable = false) 
     }) 
private List<ControlRuleAttrib> controlRuleAttribs; 

相當接近,但它給了我以下異常:

Repeated column in mapping for collection..

所以最後我刪除

joinColumns = 
{ 
    @JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false) 
} 

所有的一切都只是編譯當我嘗試達到收集時,Hibernate正在執行以下查詢:

https://gist.github.com/c88684392f0b7a62bea5

最後一行,是controlrul0_.CONTROL_RULE_CONTROL_RULE_ID=?而應該是controlrul0_.CONTROL_RULE_ID=?

有反正我可以讓它工作嗎? :/

回答

2

請參見本掙扎最後幾個小時,我終於讓我的項目中工作之後。我做的事情是這樣的:

ControlRule

@OneToMany(fetch = FetchType.LAZY, mappedBy = "controlRuleAttribPK.controlRuleId") 
@Cascade(CascadeType.ALL) 
private List<ControlRuleAttrib> controlRuleAttribs; 

基本上指向該集合應該從複合主鍵使用controlRuleId。到目前爲止它的工作很棒!

0

我不清楚哪個標識符太長,但我可以建議您可以嘗試將@Id註釋字段類型從Integer更改爲Long。獲得一些關於您的問題的詳細信息(堆棧跟蹤等)將非常有用。

+0

看到我的編輯,添加stacktrace – kamil 2012-07-10 13:44:26

+0

所以,你有ORACLE錯誤'ORA-00972'。它在[這裏]描述(http://www.techonthenet.com/oracle/errors/ora00972.php)。問題是DB對象名稱很長,所以我只能提出解決方案 - 縮短名稱。也許JPA提供者生成很長的別名,但我認爲這種情況幾乎是不可能的(即使考慮了別名)。 – gkuzmin 2012-07-10 13:54:26

+0

這是問題:/我寫公司的東西給我們提供他們自己的數據方案,沒有我可以真正用對象名稱 – kamil 2012-07-10 14:09:59

0

的問題是列

CONTROL_RULE_ATTRIB.controlRuleAttribs_CONTROL_RULE_ATTRIB_TYPE_ID 

這是這麼長時間它不可能存在於數據庫中。我沒有在這個問題看不到任何暗示它實際上是如何命名的,但我假設的正確名稱是

CONTROL_RULE_ATTRIB.CONTROL_RULE_ATTRIB_TYPE_ID 

所以,問題是:爲什麼是休眠試圖訪問此列。它是在表是在Hibernate映射爲一個映射表:

@OneToMany(fetch = FetchType.LAZY) 
@Cascade(CascadeType.ALL) 
@JoinTable(name = "CONTROL_RULE_ATTRIB", joinColumns = {@JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)}) 
private List<ControlRuleAttrib> controlRuleAttribs; 

如果你看一下@JoinTable註解,你會發現,它定義了表的名稱,因爲它的使用和連接列。但是映射表有兩組連接列。第二個未指定。因此使用您配置的NamingStrategy或者如果您未配置任何默認值。只需使用inverseJoinColumns屬性指定另一組連接列,並且所有應該都可以。

完整的註釋應該是這樣的:

@JoinTable(name = "CONTROL_RULE_ATTRIB", joinColumns = {@JoinColumn(name = "CONTROL_RULE_ID", nullable = false, updatable = false)}, inverseJoinColumns = {@JoinColumn(name = "CONTROL_RULE_ATTRIB_TYPE_ID")}) 

注:我不知道,如果你需要任何的空的,可更新的東西該列也是如此。

documentation of the JoinTable annotation

+0

我根據你的建議進行了編輯,請看我編輯過的帖子 – kamil 2012-07-11 09:23:05