论坛首页 Java企业应用论坛

[Help] 为什么 many-one 只插入一条 detail?

浏览 9355 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2003-09-24  
大伙麻烦帮我看一下, 我的 Hibernate 测试程序为什么仅仅帮我插入一条明细数据到 DB 中去, 还有一条丢失了?

TestHibernate.java
package example.hibernate;

import example.*;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.Configuration;

import java.util.*;


public class TestHibernate {
    public static void main(String[] args); {
        try {
            Configuration cf = (new Configuration(););.addClass(Player.class);
                                .addClass(Team.class);;
            SessionFactory sf = cf.buildSessionFactory();;
            Session session = sf.openSession();;
            System.out.println("Begining Transaction");;

            Transaction tx = session.beginTransaction();;
            System.out.println("Transaction Established OK!");;

            Player player1 = new Player();;
            player1.setAnnualSalary(10.5f);;
            player1.setDraftDate(new Date(););;
            player1.setFirstName("Edward");;
            player1.setLastName("Wang");;
            player1.setJerseyNumber(3);;

            Player player2 = new Player();;
            player2.setAnnualSalary(50.5f);;
            player2.setDraftDate(new Date(););;
            player2.setFirstName("Cathy");;
            player2.setLastName("Chun");;
            player2.setJerseyNumber(2);;

            Team team = new Team();;
            team.setCity("Shanghai");;
            team.setName("Edward's Team");;

            player1.setTeam(team);;
            player2.setTeam(team);;

            HashSet set = new HashSet();;
            set.add(player1);;
            System.out.println("Size is: " + set.size(););;
            set.add(player2);;
            System.out.println("Size is: " + set.size(););;
            team.setPlayers(set);;

            System.out.println("Saving...");;
            session.save(team);;
            System.out.println("Saved OK, Committing...");;
            tx.commit();;
            System.out.println("Committed OK! Quiting...");;
        } catch (Exception e); {
            e.printStackTrace();;
        }
    }
}


Players.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
	<class name="example.Player" table="players">
		<id name="id" column="player_id" type="long" unsaved-value="null">
			<generator class="hilo"/>
		</id>
		<property name="firstName" column="first_name" type="string" length="12" not-null="true"/>
		<property name="lastName" column="last_name" type="string" length="15" not-null="true"/>
		<property name="draftDate" column="draft_date" type="date"/>
		<property name="annualSalary" column="salary" type="float"/>
		<property name="jerseyNumber" column="jersey_number" type="integer" length="2" not-null="true"/>
		<many-to-one name="team" class="example.Team" column="team_id"/>
	</class>
</hibernate-mapping>


Team.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
	<class name="example.Team" table="teams">
		<id name="id" column="team_id" type="long" unsaved-value="null">
			<generator class="hilo"/>
		</id>
		<property name="name" column="team_name" type="string" length="15" not-null="true"/>
		<property name="city" column="city" type="string" length="15" not-null="true"/>
		<set name="players" cascade="all" inverse="true" lazy="true">
			<key column="team_id"/>
			<one-to-many class="example.Player"/>
		</set>
	</class>
</hibernate-mapping>


hibernate.properties
######################
### Query Language ###
######################

## define query language constants / function names

hibernate.query.substitutions true 1, false 0, yes 'Y', no 'N'

## package imports

hibernate.query.imports net.sf.hibernate.test, net.sf.hibernate.eg


## PostgreSQL

hibernate.dialect net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.connection.driver_class org.postgresql.Driver
hibernate.connection.url jdbc:postgresql:tiers
hibernate.connection.username Edward
hibernate.connection.password

#################################
### Hibernate Connection Pool ###
#################################

hibernate.connection.pool_size 1
hibernate.statement_cache.size 25

##############################
### Proxool Connection Pool###
##############################

## Properties for external configuration of Proxool

hibernate.proxool.pool_alias pool1

##############################
### Miscellaneous Settings ###
##############################

## print all generated SQL to the console

hibernate.show_sql true


## specify a JDBC isolation level

#hibernate.connection.isolation 4


## set the JDBC fetch size

hibernate.jdbc.fetch_size 50


## set the maximum JDBC 2 batch size (a nonzero value enables batching);

hibernate.jdbc.batch_size 25


## enable use of JDBC 2 scrollable ResultSets (specifying a Dialect will cause Hibernate to use a sensible default);

#hibernate.jdbc.use_scrollable_resultset true


## use streams when writing binary types to / from JDBC

hibernate.jdbc.use_streams_for_binary true


## specify a default schema for unqualified tablenames

#hibernate.default_schema test


## use a custom stylesheet for XML generation (if not specified, hibernate-default.xslt will be used);

#hibernate.xml.output_stylesheet C:/Hibernate/net/sf/hibernate/hibernate-default.xslt


## enable outerjoin fetching (specifying a Dialect will cause Hibernate to use sensible default);

#hibernate.use_outer_join false


## enable CGLIB reflection optimizer (enabled by default);

#hibernate.cglib.use_reflection_optimizer false



另外, 数据库是 PostgreSQL. 运行结束后, PostgreSQL 会报警:
LOG:  pq_recvbuf: recv() failed: Connection reset by peer
LOG:  pq_recvbuf: recv() failed: Connection reset by peer

意思是 DB Connection 打开后没有关闭 Client 就退出了.

Console 里面的 Log 是:
Begining Transaction
Transaction Established OK!
Size is: 1
Size is: 1
Saving...
Saved OK, Committing...
Hibernate: insert into teams (team_name, city, team_id); values (?, ?, ?);
Hibernate: insert into players (first_name, last_name, draft_date, salary, jersey_number, team_id, player_id); values (?, ?, ?, ?, ?, ?, ?);
Committed OK! Quiting...


谢谢大家, 初学 Hibernate.

这里是数据:

tiers=# select * from teams;
team_id |   team_name   |   city
---------+---------------+----------
2392065 | Edward's Team | Shanghai
(1 row)

tiers=# select * from players;
player_id | first_name | last_name | draft_date | salary | jersey_number | team_id
-----------+------------+-----------+------------+--------+---------------+---------
   2424833 | Edward     | Wang      | 2003-09-24 |   10.5 |             3 | 2392065
(1 row)
   发表时间:2003-09-24  
是亚, 我也怀疑, 但是 Player 类是使用 CodeGenerator 生成的, 我检查了好像也没有问题呢.
因为这里需要 inverse, 所以 Player 也引用了 Team.

我的 Eclipse 不能调试, 总是报错说: can't find a free port for the debugger, 所以我找不到错在哪里.

Player.java
package example;

import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/** @author Hibernate CodeGenerator */
public class Player implements Serializable {

    /** identifier field */
    private Long id;

    /** persistent field */
    private String firstName;

    /** persistent field */
    private String lastName;

    /** nullable persistent field */
    private java.util.Date draftDate;

    /** nullable persistent field */
    private float annualSalary;

    /** persistent field */
    private int jerseyNumber;

    /** nullable persistent field */
    private example.Team team;

    /** full constructor */
    public Player(java.lang.String firstName, java.lang.String lastName, java.util.Date draftDate, float annualSalary, int jerseyNumber, example.Team team); {
        this.firstName = firstName;
        this.lastName = lastName;
        this.draftDate = draftDate;
        this.annualSalary = annualSalary;
        this.jerseyNumber = jerseyNumber;
        this.team = team;
    }

    /** default constructor */
    public Player(); {
    }

    /** minimal constructor */
    public Player(java.lang.String firstName, java.lang.String lastName, int jerseyNumber); {
        this.firstName = firstName;
        this.lastName = lastName;
        this.jerseyNumber = jerseyNumber;
    }

    public java.lang.Long getId(); {
        return this.id;
    }

    public void setId(java.lang.Long id); {
        this.id = id;
    }

    public java.lang.String getFirstName(); {
        return this.firstName;
    }

    public void setFirstName(java.lang.String firstName); {
        this.firstName = firstName;
    }

    public java.lang.String getLastName(); {
        return this.lastName;
    }

    public void setLastName(java.lang.String lastName); {
        this.lastName = lastName;
    }

    public java.util.Date getDraftDate(); {
        return this.draftDate;
    }

    public void setDraftDate(java.util.Date draftDate); {
        this.draftDate = draftDate;
    }

    public float getAnnualSalary(); {
        return this.annualSalary;
    }

    public void setAnnualSalary(float annualSalary); {
        this.annualSalary = annualSalary;
    }

    public int getJerseyNumber(); {
        return this.jerseyNumber;
    }

    public void setJerseyNumber(int jerseyNumber); {
        this.jerseyNumber = jerseyNumber;
    }

    public example.Team getTeam(); {
        return this.team;
    }

    public void setTeam(example.Team team); {
        this.team = team;
    }

    public String toString(); {
        return new ToStringBuilder(this);
            .append("id", getId(););
            .toString();;
    }

    public boolean equals(Object other); {
        if ( !(other instanceof Player); ); return false;
        Player castOther = (Player); other;
        return new EqualsBuilder();
            .append(this.getId();, castOther.getId(););
            .isEquals();;
    }

    public int hashCode(); {
        return new HashCodeBuilder();
            .append(getId(););
            .toHashCode();;
    }

}


Team.java
package example;

import java.io.Serializable;
import java.util.Set;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/** @author Hibernate CodeGenerator */
public class Team implements Serializable {

    /** identifier field */
    private Long id;

    /** persistent field */
    private String name;

    /** persistent field */
    private String city;

    /** persistent field */
    private Set players;

    /** full constructor */
    public Team(java.lang.String name, java.lang.String city, Set players); {
        this.name = name;
        this.city = city;
        this.players = players;
    }

    /** default constructor */
    public Team(); {
    }

    public java.lang.Long getId(); {
        return this.id;
    }

    public void setId(java.lang.Long id); {
        this.id = id;
    }

    public java.lang.String getName(); {
        return this.name;
    }

    public void setName(java.lang.String name); {
        this.name = name;
    }

    public java.lang.String getCity(); {
        return this.city;
    }

    public void setCity(java.lang.String city); {
        this.city = city;
    }

    public java.util.Set getPlayers(); {
        return this.players;
    }

    public void setPlayers(java.util.Set players); {
        this.players = players;
    }

    public String toString(); {
        return new ToStringBuilder(this);
            .append("id", getId(););
            .toString();;
    }

    public boolean equals(Object other); {
        if ( !(other instanceof Team); ); return false;
        Team castOther = (Team); other;
        return new EqualsBuilder();
            .append(this.getId();, castOther.getId(););
            .isEquals();;
    }

    public int hashCode(); {
        return new HashCodeBuilder();
            .append(getId(););
            .toHashCode();;
    }

}


另外, 这里保存了 Team 是不是就会自动把 Detail 里面的 Players 保存? 还是说我需要手动保存 player1, player2?

再有, 我发现 flush 与否好像都没有关系的.


以下代码手动保存 player1,2 居然就正确了, 保存了两条记录, flush 注释掉与否也没有关系:
session.save(team);;
session.save(player1);;
session.save(player2);;
//session.flush();;


tiers=# select * from players;
player_id | first_name | last_name | draft_date | salary | jersey_number | team_id
-----------+------------+-----------+------------+--------+---------------+---------
   2359297 | Edward     | Wang      | 2003-09-24 |   10.5 |             3 | 2326529
   2359298 | Cathy      | Chun      | 2003-09-24 |   50.5 |             2 | 2326529
(2 rows)

tiers=# select * from teams;
team_id |   team_name   |   city
---------+---------------+----------
2326529 | Edward's Team | Shanghai
(1 row)

怪事.
0 请登录后投票
   发表时间:2003-09-24  
真是搞不懂了.

就算我 Close 了 Session, PostgreSQL 还是说我没有关闭连接就退出客户端了.

System.out.println("Committed OK! Quiting...");;
session.connection();.close();;
session.close();;


LOG:  pq_recvbuf: recv() failed: Connection reset by peer

:'(
0 请登录后投票
   发表时间:2003-09-24  
 public boolean equals(Object other); { 
        if ( !(other instanceof Player); ); return false; 
        Player castOther = (Player); other; 
        return new EqualsBuilder(); 
            .append(this.getId();, castOther.getId();); 
            .isEquals();; 
    } 

比较两个id都为null的Player是不是为true,若是,问题就在这里。

commit()时会调用flush()的。
0 请登录后投票
   发表时间:2003-09-24  
两个cascade
0 请登录后投票
   发表时间:2003-09-25  
多谢. 我试一下, 请问两个 cascade 什么意思?
0 请登录后投票
   发表时间:2003-09-25  
不行啊, 两个 cascade 在 hbm2java 时会出错的.

11:26:15,074 ERROR CodeGenerator:43 - Error parsing XML: file:/D:/eclipse/worksp
ace/JDemo/Hibernate/example/Team.hbm.xml(10)
org.xml.sax.SAXParseException: Attribute "cascade" already appeared in this tag.
0 请登录后投票
   发表时间:2003-09-25  
引用

&lt;set name="players" cascade="all" inverse="true" lazy="true" cascade="all"&gt;

这里面有两个cascade,错了。
0 请登录后投票
   发表时间:2003-09-25  
yehs220 老大, 到底该怎么搞呀? 两个 cascade 应该是不行的.
0 请登录后投票
   发表时间:2003-09-25  
去掉一个就好了呀!
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics