2010-02-10 75 views
1

你好我有以下類:Hibernate的一個一對一的映射問題

public class Movimenti implements java.io.Serializable { 

private Integer id = null; 
private Integer idCommessa = null; 
private String nomemovimento = null; 
private Movimento preventivato = null; 
private Movimento effettivo = null; 

public Movimento getEffettivo() { 
    return effettivo; 
} 

public void setEffettivo(Movimento effettivo) { 
    this.effettivo = effettivo; 
} 

public Movimento getPreventivato() { 
    return preventivato; 
} 

public void setPreventivato(Movimento preventivato) { 
    this.preventivato = preventivato; 
} 

public Movimenti() { 
} 

public Movimenti(Integer idCommessa, String nomemovimento) { 
    this.idCommessa = idCommessa; 
    this.nomemovimento = nomemovimento; 
} 

public Integer getId() { 
    return this.id; 
} 

public void setId(Integer id) { 
    this.id = id; 
} 

public Integer getIdCommessa() { 
    return this.idCommessa; 
} 

public void setIdCommessa(Integer idCommessa) { 
    this.idCommessa = idCommessa; 
} 

public String getNomemovimento() { 
    return this.nomemovimento; 
} 

public void setNomemovimento(String nomemovimento) { 
    this.nomemovimento = nomemovimento; 
} 

}

正如你可以看到有兩個MOVIMENTO引用。 Movimento看起來像這樣:

public class Movimento { 

    Integer id = null; 
    Movimenti movimenti; 
    String descrizione = null; 

    public Movimenti getMovimenti() { 
     return movimenti; 
    } 

    public void setMovimenti(Movimenti movimenti) { 
     this.movimenti = movimenti; 
    } 

    public String getDescrizione() { 
     return descrizione; 
    } 

    public void setDescrizione(String descrizione) { 
     this.descrizione = descrizione; 
    } 

    public Integer getId() { 
     return id; 
    } 

    public void setId(Integer id) { 
     this.id = id; 
    } 
} 

在movimento中提到了Movimenti。現在movimento是其他類的基類,因爲SchemaExport沒有正確地執行他的工作,所以它沒有問題。我想要的是在Movimento和Movimenti之間建立一對一的關係,這樣當我加載Movimenti實例時,Movimento可以自動恢復,反之亦然,並自動刪除孤立的Movimento對象。所以我想到了Movimenti將兩個一對一的關係放到了Movimento,另一個關係倒退了。但它不起作用,它不會生成正確的數據庫表,甚至會發出異常。這些是映射(甚至有我不包括的子類)。

Movimento.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping> 
    <class dynamic-insert="false" dynamic-update="false" mutable="true" name="persistence.beans.jCommesse.Movimento" optimistic-lock="version" polymorphism="implicit" select-before-update="false"> 
     <id name="id" type="java.lang.Integer"> 
      <column name="id" /> 
      <generator class="identity" /> 
     </id> 
     <property name = "descrizione" type="java.lang.String"> 
      <column name = "descrizione"></column> 
     </property> 
     <one-to-one name = "movimenti" class = "persistence.beans.jCommesse.Movimento" constrained="true"> 

     </one-to-one> 
     <joined-subclass name = "persistence.beans.jCommesse.Materiali" table = "Materiali"> 
      <key column="id"/> 
      <property name = "consegnato" type="java.lang.Boolean"> 
       <column name = "consegnato"/> 
      </property> 
      <property name="costo" type = "java.lang.Double"> 
       <column name = "costo"/> 
      </property> 
      <property name = "costoTrasporto" type = "java.lang.Double"> 
       <column name = "costoTrasporto"/> 
      </property> 
      <property name = "quantita" type = "java.lang.Double"> 
       <column name = "quantita"/> 
      </property> 
      <property name = "riferimentoFattura" type = "java.lang.Integer"> 
       <column name = "riferimentoFattura"/> 
      </property> 
      <property name = "tipoQuantita" type = "java.lang.String"> 
       <column name = "tipoQuantita"/> 
      </property> 
     </joined-subclass> 

     <joined-subclass name = "persistence.beans.jCommesse.RientroMateriali" table = "RientroMateriali"> 
      <key column="id"/> 
      <property name = "costo" type = "java.lang.Double"> 
       <column name = "costo"/> 
      </property> 
      <property name = "costoDelTrasporto" type = "java.lang.Double"> 
       <column name = "costoDelTrasporto"/> 
      </property> 
      <property name = "quantita" type = "java.lang.Double"> 
       <column name = "quantita"/> 
      </property> 
      <property name = "riferimentoFattura" type = "java.lang.Integer"> 
       <column name = "riferimentoFattura"/> 
      </property> 
      <property name = "tipoQuantita" type = "java.lang.String"> 
       <column name = "tipoQuantita"/> 
      </property> 
     </joined-subclass> 

     <joined-subclass name = "persistence.beans.jCommesse.CostiExtra" table = "CostiExtra"> 
      <key column = "id"/> 
      <property name = "nota" type = "java.lang.String"> 
       <column name = "nota"/> 
      </property> 
      <property name = "prezzo" type = "java.lang.Double"> 
       <column name = "prezzo"/> 
      </property> 
     </joined-subclass> 
    </class> 
</hibernate-mapping> 

和Movimenti.hbm.xml

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
<!-- Generated 10-feb-2010 11.24.48 by Hibernate Tools 3.2.1.GA --> 
<hibernate-mapping> 
    <class name="persistence.beans.jCommesse.Movimenti" table="movimenti" catalog="jcommesse"> 
     <id name="id" type="java.lang.Integer"> 
      <column name="id" /> 
      <generator class="identity" /> 
     </id> 
     <property name="idCommessa" type="java.lang.Integer"> 
      <column name="idCommessa" /> 
     </property> 
     <property name="nomemovimento" type="string"> 
      <column name="nomemovimento" length="250" /> 
     </property> 


     <one-to-one name="preventivato" class="persistence.beans.jCommesse.Movimento" cascade="all" /> 



    </class> 
</hibernate-mapping> 

這一切不創建表,而是出現與這個討厭的例外:

10-feb-2010 15.04.46 org.hibernate.tool.hbm2ddl.SchemaUpdate execute 
INFO: schema update complete 
Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: persistence.beans.jCommesse.Materiali.movimenti 
     at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72) 
     at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:290) 
     at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181) 
     at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107) 
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187) 
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172) 
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94) 
     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) 
     at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507) 
     at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499) 
     at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495) 
     at testgeneration.testSchema(testgeneration.java:34) 
     at testgeneration.main(testgeneration.java:53) 
Java Result: 1 

你可以看到它說「模式生成完成」(我正在使用更新的開發)。

Movimenti和MOVIMENTO出來這樣在MySQL:

CREATE TABLE `movimenti` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `idCommessa` int(11) DEFAULT NULL, 
    `nomemovimento` varchar(250) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

CREATE TABLE `movimento` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `descrizione` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `FKBEB397FC4778E205` (`id`), 
    CONSTRAINT `FKBEB397FC4778E205` FOREIGN KEY (`id`) REFERENCES `movimento` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1 

回答

1

我發現了幾個問題:

  1. 唯一的例外是因爲使用類Materiali(它也有一個字段movimenti,必須是no n-null,但這與你的問題沒有關係,你被它弄糊塗了)。

  2. 在映射Movimenti.hbm.xml中,您忘記映射preventivatoeffettivo這兩個字段。你必須用reverse=true來映射它們。

  3. 我真的建議爲映射使用註釋。它們更簡單易用,並將所有信息保存在一個地方。

  4. 您在兩張表中看不到任何引用的原因是因爲Hibernate創建了多對多映射(需要第三張表)。我明白你想要達到的目標,但我不確定Hibernate是否足夠聰明。

+0

這個(和現在唯一的)答案怎麼會有「-1」票? – mlvljr 2010-02-19 19:47:18