论坛首页 Java版 Hibernate

[提问]one-to-one

浏览 2612 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2004-09-23
用户信息表:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="com.test.bean" auto-import="true">
<class name="Userinfo" table="userinfo" lazy="true">
<id name="id" column="id" unsaved-value="-1">
<generator class="foreign">
<param name="property">users</param>
</generator>
</id>
<property name="street">
</property>
<property name="postId">
</property>
<one-to-one name="users" class="Users" constrained="true" />
</class>
</hibernate-mapping>

用户表:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping package="com.test.bean">
    <class name="Users" table="users">
<id name="id" column="id" unsaved-value="-1">
            <generator class="identity"/>
        </id>
        <property name="username"/>
<one-to-one name="userinfo" class="Userinfo" cascade="all" />
    </class>
</hibernate-mapping>


用户和用户信息是一对一的关系 使用 users的id 值(必须的)做关联,


Users users = new Users();
users.setUsername("test1");
Userinfo userinfo = new Userinfo();
userinfo.setPostId("1234567");
userinfo.setStreet("china_gd");
users.setUserinfo(userinfo);
session.save(users);

问题就出在这里
test:
     [java] .- Hibernate 2.1.4
     [java] - loaded properties from resource hibernate.properties: {hibernate.connection.driver_class=com.mysql.jdbc.Driver,

hibernate.cglib.use_reflection_optimizer=true, hibernate.dialect=net.sf.hibernate.dialect.MySQLDialect,

hibernate.jdbc.use_streams_for_binary=true, hibernate.jdbc.batch_size=0, hibernate.query.substitutions=true 1, false 0, yes

'Y', no 'N', hibernate.query.imports=net.sf.hibernate.test, net.sf.hibernate.eg, hibernate.use_outer_join=true,

hibernate.connection.username=root, hibernate.connection.url=jdbc:mysql://localhost:3306/test?

autoReconnect=true&useUnicode=true&characterEncoding=GB2312, hibernate.show_sql=true, hibernate.connection.password=,

hibernate.statement_cache.size=25, hibernate.connection.pool_size=1}
     [java] - using java.io streams to persist binary types
     [java] - using CGLIB reflection optimizer
     [java] - Mapping resource: com/test/bean/Users.hbm.xml
     [java] - Mapping class: com.test.bean.Users -> users
     [java] - Mapping resource: com/test/bean/Userinfo.hbm.xml
     [java] - Mapping class: com.test.bean.Userinfo -> userinfo
     [java] - processing one-to-many association mappings
     [java] - processing one-to-one association property references
     [java] - processing foreign key constraints
     [java] - Using dialect: net.sf.hibernate.dialect.MySQLDialect
     [java] - Use outer join fetching: true
     [java] - Using Hibernate built-in connection pool (not for production use!)
     [java] - Hibernate connection pool size: 1
     [java] - using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost:3306/test?

autoReconnect=true&useUnicode=true&characterEncoding=GB2312
     [java] - connection properties: {user=root, password=}
     [java] - No TransactionManagerLookup configured (in JTA environment, use of process level read-write cache is not

recommended)
     [java] - Use scrollable result sets: true
     [java] - Use JDBC3 getGeneratedKeys(): true
     [java] - Optimize cache for minimal puts: false
     [java] - echoing all SQL to stdout
     [java] - Query language substitutions: {no='N', true=1, yes='Y', false=0}
     [java] - cache provider: net.sf.ehcache.hibernate.Provider
     [java] - instantiating and configuring caches
     [java] - building session factory
     [java] - no JNDI name configured
     [java] Hibernate: insert into users (username) values (?)
     [java] Hibernate: update userinfo set street=?, postId=? where id=?
    
[java] - Could not synchronize database state with session
     [java] net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)
     [java] at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:25)


错误的原因应该是出现下面的顺序
[java] Hibernate: insert into users (username) values (?)
[java] Hibernate: update userinfo set street=?, postId=? where id=?

(应该 insert 两个表才对的,怎会去update userinfo)
能够帮-帮-忙吗? :cry:  :cry: 
   
最后更新时间:2004-09-22
这个问题完全可以通过hibernate手册查找到相应答案。里面详细讲到了关于一对一关系的关联映射。
你可以去查看一下。
如果嫌english,有中文,google it
   
0 请登录后投票
最后更新时间:2004-09-23
firebody 写道
这个问题完全可以通过hibernate手册查找到相应答案。里面详细讲到了关于一对一关系的关联映射。
你可以去查看一下。
如果嫌english,有中文,google it


手册上面,和这个论坛的one-to-one的例子跟我这个有区别的:


用户和用户信息是一对一的关系 使用 users的id 值(必须的)做关联,

如果:
userinfo.hbm.xml 中的
<id name="id" column="id" unsaved-value="-1">
<generator class="foreign">
<param name="property">users</param>
</generator>

</id>
改为:
<id name="id" column="id" unsaved-value="-1">
<generator class="indentity">

</generator>

</id>
users.hbm.xml
<class name="Users" table="users">
<id name="id" column="id" unsaved-value="-1">
            <generator class="identity"/>        </id>
改为:
<id name="id" column="id" unsaved-value="-1">
<generator class="foreign">
<param name="property">userinfo</param> </generator>

</id>


然后:

Userinfo userinfo = new Userinfo();
userinfo.setPostId("1234567");
userinfo.setStreet("china_gd");
Users users = new Users();
users.setUsername("test1");
userinfo.setUsers(users);
session.save(userinfo);

这样是正确的,但是 id 就是在 userinfo的表产生,users中的id 是引用userinfo中的id,虽然这样也行,但是以后如果增加一个address的表要和users做one-to-one,这样就会出现问题了,不好扩展了,我需要session.save(users) ,不是 session.save(userinfo);
也就是:users表中的id为自动递增,其他和他做one-to-one关联的表的id 为users表中的id,然后我session.save(users),就可以把所有数据存在各个表中。

就是:
users.hbm.xml:<generator class="identity"/>
userinfo.hbm.xml:
<generator class="foreign">
<param name="property">userinfo</param> </generator>


所以还需要大家多多帮忙。。。 :cry:  :cry:  :cry:
firebody 老兄还需要帮忙顶一下。。
   
0 请登录后投票
最后更新时间:2004-09-23
试试看将User的one-to-one中cascade="all"改为cascade="delete"

虽然我同意你以User为主的关联关系,但是实际使用上可能会遇到另外的麻烦,
因为你这样就是要双向one-to-one,那么我要对UserInfo做lazy load,就要求User受UserInfo唯一约束(不知道是不是还有别的方法),即User这边Outer-Join="true" or "auto", constrained="true",从而User与UserInfo的关系产生矛盾。于是我只有选择单向one-to-one,以UserInfo为主,User受UserInfo就没问题了。
   
0 请登录后投票
最后更新时间:2004-09-23
one-to-one的关联我很少作,但是我看了一下文档,就着我的理解,分析了一下你的影射定义。
one-to-one的双向关联应该用one-to-one and many-to-one来作关联。
把你的第一个帖子里的映射改为这个形式应该就没有问题。
公用主键的one-to-one的关联总是认为他所关联的entity已经存在。
这单,你应该注意。
   
0 请登录后投票
最后更新时间:2004-09-23
[code:1]用户信息表:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="com.test.bean" auto-import="true">
<class name="Userinfo" table="userinfo" lazy="true">

<generator class="increment"/>

<property name="street">
</property>
<property name="postId">
</property>
<many-to-one name="users" class="Users" unique="true" />
</class>
</hibernate-mapping>

用户表:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping SYSTEM "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping package="com.test.bean">
<class name="Users" table="users">

<generator class="identity"/>

<property name="username"/>
<one-to-one name="userinfo" class="Userinfo" cascade="all" />
</class>
</hibernate-mapping> [/code:1]

试试上面的映射
   
0 请登录后投票
最后更新时间:2004-09-25
我看了hibernate in action 中的one 2 one 的例子。我自己写了一个在我的机器上成功运行。

users :user_id(pk identity),name,age

address:address_id(pk),address_context

Users.hbm.xml
[code:1]
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping package="hibernate.sample.db">
<class name="Users" table="users">
<id
column="user_id"
name="Id"
type="integer"
>
<generator class="identity"    />
</id>
<property
column="age"
length="10"
name="Age"
not-null="false"
type="integer"
/>
<property
column="name"
length="50"
name="Name"
not-null="false"
type="string"
/>
<one-to-one name="address" class="hibernate.sample.db.Address" cascade="all" />
</class>
</hibernate-mapping>
[/code:1]

Address.hbm.xml
[code:1]
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping package="hibernate.sample.db">
<class name="Address" table="address">
<id
column="address_id"
name="Id"
type="integer"
>
<generator class="foreign" >

<param name="property">user</param>

</generator>
</id>
<property
column="address_context"
length="255"
name="AddressContext"
not-null="false"
type="string"
/>
<one-to-one name="user" class="hibernate.sample.db.Users" constrained="true"/>
</class>
</hibernate-mapping>
[/code:1]

test.java

[code:1]
·············
        try {
            Session session = HibernateUtil.currentSession();
            Transaction tx = session.beginTransaction();
           
            Users dengyin = new Users();
            dengyin.setName("邓胤");
            dengyin.setId(new Integer(20));
            Address dengyin_a = new Address();
            dengyin_a.setAddressContext("footmark1");
            dengyin_a.setUser(dengyin);
            dengyin.setAddress(dengyin_a);
            session.save(dengyin);
      
           
          session.flush();
           
            tx.commit();
            HibernateUtil.closeSession();
            System.out.print("插入成功!");
        } catch (HibernateException e) {

            e.printStackTrace();
        }
················
[/code:1]

[/quote]
   
0 请登录后投票
最后更新时间:2004-11-27
如果一对一中的外键不是主键映射文件应该怎么写,譬如:我的address表中用个username字段跟userinfo的username关联,可是我的userinfo表的主键是userid
   
0 请登录后投票
最后更新时间:2004-11-29
one-to-one的查询是不是很低。能否帮忙看看下面的帖子。
http://forum.javaeye.com/viewtopic.php?t=9074
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐