简体   繁体   English

休眠一对一映射问题

[英]Hibernate one-to-one mapping problem

Hello I've the following class: 您好,我上了以下课程:

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;
}

} }

As you can see there are two Movimento references. 如您所见,有两个Movimento参考。 Movimento looks like this: 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;
    }
}

there is a reference to Movimenti in movimento. 在movimento中有对Movimenti的引用。 Now movimento is a base class for other classes and that gives no problems as SchemaExport does his job correctly. 现在,movimento是其他类的基类,并且由于SchemaExport正确完成其工作,因此不会出现任何问题。 What I want is to have a one-to-one relationship between Movimento and Movimenti, so that I can have automatic retrivial of Movimento when I load up a Movimenti instance and vice versa and automatic deletion of orphaned Movimento objects. 我想要的是在Movimento和Movimenti之间建立一对一的关系,这样,当我加载Movimenti实例时,我可以自动重导Movimento,反之亦然,并且可以自动删除孤立的Movimento对象。 So I thought of putting two one-to-one relationships in Movimenti towards Movimento and one backwards. 因此,我想到了在Movimenti中将两个一对一的关系放到Movimento上,然后再倒向一个。 But it doesn't work, it doesn't generate the correct database tables and it even gives out exceptions. 但是它不起作用,它不会生成正确的数据库表,甚至会发出异常。 These are the mappings (there are even the subclasses that I don't include). 这些是映射(甚至还有我不包含的子类)。

Movimento.hbm.xml: 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>

and Movimenti.hbm.xml 和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>

all this doesn't create the tables but instead comes out with this nasty exception: 所有这些都不会创建表,而是会出现以下讨厌的异常:

    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

as you can see it says "schema generation complete" (I'm using update for development). 如您所见,它说“模式生成已完成”(我正在使用更新进行开发)。

Movimenti and Movimento come out like this on mySQL: 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

and

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

I've found a couple of issues: 我发现了几个问题:

  1. The exception is because of a bug in the use of the class Materiali (it also has a field movimenti that must be non-null but that's not related to your question and you're confused by it). 例外是由于在使用Materiali类时出现的错误(它也具有字段movimenti ,该字段必须为非null,但与您的问题无关,并且对此感到困惑)。

  2. In the mapping Movimenti.hbm.xml , you forgot to map the two fields preventivato and effettivo . 在映射Movimenti.hbm.xml ,您忘记映射了两个字段preventivatoeffettivo You must map them with reverse=true . 您必须使用reverse=true映射它们。

  3. I really suggest to use annotations for the mapping. 我真的建议对地图使用注解。 They are much more simple to use and keep all the information in one place. 它们更易于使用,并将所有信息保存在一个地方。

  4. The reason why you don't see any references in the two tables is because Hibernate creates a many-to-many mapping (which needs a third table). 在两个表中看不到任何引用的原因是因为Hibernate创建了多对多映射(需要第三个表)。 I understand what you're trying to achieve but I'm not sure Hibernate is smart enough to do it. 我了解您要达到的目标,但是我不确定Hibernate是否足够聪明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM