Hibernate映射问题与composite-id

时间:2010-04-14 12:55:10

标签: java hibernate composite-id

我在我的java应用程序中使用hibernate3来访问sqlserver 2008企业。 hibernate映射使用复合id,当我尝试加载模型时,它返回null。我花了好几天才解决它,但仍然没有结果。复合id映射应该用于多个基于字段的PK,但在我的表中没有这样的PK,我想知道为什么JBoss Hibernate Tool(eclipse插件)用复合id映射生成它?

感谢任何帮助或评论。

Hibernate Models:

public class AuthorLoginTrack implements java.io.Serializable {

private AuthorLoginTrackId id;

public AuthorLoginTrack() {
}

public AuthorLoginTrack(AuthorLoginTrackId id) {
    this.id = id;
}

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

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

}

public class AuthorLoginTrackId implements java.io.Serializable {

private long id;
private String userId;
private Date dateCreated;

public AuthorLoginTrackId() {
}

public AuthorLoginTrackId(long id, String userId) {
    this.id = id;
    this.userId = userId;
}

public AuthorLoginTrackId(long id, String userId, Date dateCreated) {
    this.id = id;
    this.userId = userId;
    this.dateCreated = dateCreated;
}

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

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

public String getUserId() {
    return this.userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

public Date getDateCreated() {
    return this.dateCreated;
}

public void setDateCreated(Date dateCreated) {
    this.dateCreated = dateCreated;
}

public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof AuthorLoginTrackId))
        return false;
    AuthorLoginTrackId castOther = (AuthorLoginTrackId) other;

    return (this.getId() == castOther.getId())
            && ((this.getUserId() == castOther.getUserId()) || (this
                    .getUserId() != null
                    && castOther.getUserId() != null && this.getUserId()
                    .equals(castOther.getUserId())))
            && ((this.getDateCreated() == castOther.getDateCreated()) || (this
                    .getDateCreated() != null
                    && castOther.getDateCreated() != null && this
                    .getDateCreated().equals(castOther.getDateCreated())));
}

public int hashCode() {
    int result = 17;

    result = 37 * result + (int) this.getId();
    result = 37 * result
            + (getUserId() == null ? 0 : this.getUserId().hashCode());
    result = 37
            * result
            + (getDateCreated() == null ? 0 : this.getDateCreated()
                    .hashCode());
    return result;
}

}

Hibernate Mapping:

<?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 Apr 6, 2010 4:17:46 PM by Hibernate Tools 3.3.0.GA -->
<hibernate-mapping>
    <class name="com.entity.model.AuthorLoginTrack" table="AuthorLoginTrack" schema="dbo" catalog="tribetoyota_db">
        <composite-id name="id" class="com.entity.model.AuthorLoginTrackId">
            <key-property name="id" type="long">
                <column name="ID" precision="18" scale="0" />
            </key-property>
            <key-property name="userId" type="string">
                <column name="UserID" length="20" />
            </key-property>
            <key-property name="dateCreated" type="timestamp">
                <column name="DateCreated" length="16" />
            </key-property>
        </composite-id>
    </class>
</hibernate-mapping>

表转储:

/****** Object:  Table [dbo].[AuthorLoginTrack]    Script Date: 04/14/2010 20:43:02 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[AuthorLoginTrack](
    [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
    [UserID] [varchar](20) NOT NULL,
    [DateCreated] [smalldatetime] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[AuthorLoginTrack] ADD  CONSTRAINT [DF_AuthorLoginTrack_DateCreated]  DEFAULT (getdate()) FOR [DateCreated]
GO

表:

ID  UserID   DateCreated
------------------------------------
5   cooler   2005-03-17 18:56:00
6   miumiu   2005-03-17 19:46:00

DAO代码:

AuthorLoginTrack track;
AuthorLoginTrackId trackId; 

trackId = new AuthorLoginTrackId();
trackId.setId(5);

track = (AuthorLoginTrack)getSession().load(AuthorLoginTrack.class, trackId);
return track.getId().getUserId(); // returns null why ?:((

1 个答案:

答案 0 :(得分:0)

Session.load(...)假设确实存在具有给定id的实例,大多数情况下它将返回代理对象而不会访问数据库。你真正查询的是一个id为5的实例,userId = null,date == null。

基本上,您将获得一个单元化代理,其中包含您用于查询它的复合ID的副本。如果实例确实存在,那么你会没事的,否则你第一次尝试使用该对象时会得到一个ObjectNotFoundException。