Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 映射同一类关系-延续_Java_Hibernate_Orm - Fatal编程技术网

Java 映射同一类关系-延续

Java 映射同一类关系-延续,java,hibernate,orm,Java,Hibernate,Orm,这篇文章是这篇文章的延续 我有DlUser类该类的每个对象可能有DLFaceBook类,DLFaceBook的每个对象都可以有映射为myFriends的朋友 我正在尝试使用包映射、复合主键和静态内部类来映射同一类的关系和多对多关系。我的代码如下: public class DlUser{ public DlUser(){} Long Id; String FirstName; String LastName; .... DlFaceBook fbuser; //// all req

这篇文章是这篇文章的延续

我有DlUser类该类的每个对象可能有DLFaceBook类,DLFaceBook的每个对象都可以有映射为myFriends的朋友

我正在尝试使用包映射、复合主键和静态内部类来映射同一类的关系和多对多关系。我的代码如下:

public class DlUser{
 public DlUser(){}
 Long Id;
 String FirstName;
 String LastName;
 ....
 DlFaceBook fbuser;
 //// all requred 
 getters and setters...
}
Facebook用户类看起来像这样,正如您可以看到的,我有一个对象集合,它包含MyFriends类:

public class DlFaceBook {
private long dlpId;
private String FbId;
private Collection<MyFriends> Friends;
public DlFaceBook(){}
public void setFbId(String FbId)
{
    this.FbId = FbId;
}
public void setFriends(Collection<MyFriends> friends)
{
    this.Friends = friends;
}
public Collection<MyFriends> getFriends()
{
    return this.Friends;
}
public void setdlpId(long id)
{
    this.dlpId = id;
}
public long getdlpId()
{
    return this.dlpId;
}
public String getFbId()
{
    return this.FbId;
}
}
现在,映射:

DlUser.hbm.xml如下所示,非常简单:

<hibernate-mapping>
  <class name="DlUser" table="Users">
  <id name="Id" column="id" >
<generator class="sequence">
                <param name="sequence">userseq</param>
            </generator>        
 </id>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
 <property name="firstName">
     <column name="FirstName" />
  </property>
  <property name="lastName">
    <column name="LastName"/>
  </property>
 <many-to-one
            name="FaceBook"
            class="DlFaceBook"
            cascade="all"
            column="dlpId"
            unique="true" 
        />
 </class>
</hibernate-mapping>

我发现当我们试图更新不存在的行时会发生此错误,但我如何才能使此代码正常工作?

只有Facebook和MyFriends

Facebook注意添加便利方法和MutableLong(稍后,我会告诉你为什么要使用MutableLong)

映射

<hibernate-mapping package="br.com._3845772.model.domain">
    <class name="User">
        <id name="id">
            <generator class="native"/>
        </id>
        <many-to-one cascade="all" class="Facebook" name="facebook"/>
    </class>
    <class name="Facebook">
        <id name="id">
            <generator class="native"/>
        </id>
        <bag cascade="all" name="myFriends">
            <key column="ME_FACEBOOK_ID" update="false"/>
            <one-to-many class="MyFriends"/>
        </bag>
    </class>
    <class name="MyFriends">
        <composite-id class="MyFriends$MyFriendsId" name="myFriendId">
            <key-property column="ME_FACEBOOK_ID" name="meId"/>
            <key-property column="MY_FRIEND_FACEBOOK_ID" name="myFriendId"/>
        </composite-id>
        <many-to-one class="Facebook" column="ME_FACEBOOK_ID" insert="false" name="me" update="false"/>
        <many-to-one class="Facebook" column="MY_FRIEND_FACEBOOK_ID" insert="false" name="myFriend" update="false"/>
    </class>
</hibernate-mapping>
这让我

Hibernate: insert into Facebook values ( )
Hibernate: insert into Facebook values ( )
Hibernate: select myfriends_.ME_FACEBOOK_ID, myfriends_.MY_FRIEND_FACEBOOK_ID from MyFriends myfriends_ where myfriends_.ME_FACEBOOK_ID=? and myfriends_.MY_FRIEND_FACEBOOK_ID=?
Hibernate: insert into MyFriends (ME_FACEBOOK_ID, MY_FRIEND_FACEBOOK_ID) values (?, ?)
几张便条

  • Hibernate不支持自动生成复合主键保存前必须设置其值
  • 您的数据库必须支持目标生成器策略(如果您不知道数据库支持哪种生成器策略,请使用本机策略)
  • 每个实体必须提供一个无参数构造函数
现在,为什么不使用Long而使用MutableLong(通过Long属性封装)呢


Number及其子类(Long是一个数)是不可变的。因此,如果您希望Facebook.id(由数据库配置)与其对应的MyFriend$MyFriendId.meId共享相同的值,则必须使用MutableLong。当数据库设置Facebook.id时,MyFriend$MyFriendId.meId自动获取其最新值。但是如果您使用可变长度,则会发生这种情况。

如果您试图更新一个不存在的行,那么这种情况如何发生?它可以工作:)非常感谢。我从你的例子中学到了很多。我很高兴。1)这对我不起作用(在
MyFriends
表中更改一个复合键的值会导致在该表中创建新记录,删除根本不起作用)。2) 这个解决方案可以按原样工作,但只适用于将新记录保存到
MyFriends
表中。当从DB加载
Facebook
实体时,Hibernate调用
MyFriendsId
上的默认构造函数,因此
MyFriendsId.meId
MyFriendsId.myFriendId
为null,并且在某个点抛出null异常。在默认构造函数中创建新实例违背了使用Mutable的目的?对象作为ID(值仍不共享)。
<hibernate-mapping>
  <class name="MyFriends">
  <composite-id name="myFriendId" class="MyFriends$MyFriendsId">
        <key-property name="meId"/>
        <key-property name="myFrId"/>
    </composite-id>
    <many-to-one name="me" class="DlFaceBook" insert="false" update="false"/>
    <many-to-one name="myFriend" class="DlFaceBook" insert="false" update="false"/>
    </class>
    </hibernate-mapping>
Hibernate: insert into dlfacebook (fbId, dlpId) values (?, ?)
Hibernate: insert into Users (FirstName, LastName, email, twitter, birthday, dlpId, id) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: update MyFriends set me_Id=? where meId=? and myFrId=?
Hibernate: update MyFriends set me_Id=? where meId=? and myFrId=?
Oct 2, 2010 1:21:18 PM org.hibernate.jdbc.BatchingBatcher doExecuteBatch
SEVERE: Exception executing batch: 
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
    at Test.main(Test.java:54)
Oct 2, 2010 1:21:18 PM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
SEVERE: Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
    at Test.main(Test.java:54)
Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
public class Facebook {

    private MutableLong id = new MutableLong();
    public Long getId() { return id.longValue(); }
    public void setId(Long id) { this.id.setValue(id); }

    public MutableLong getIdAsMutableLong() {
        return id;
    }

    private Collection<MyFriends> myFriends = new ArrayList<MyFriends>();
    public Collection<MyFriends> getMyFriends() { return myFriends; }
    public void setMyFriends(Collection<MyFriends> myFriends) { this.myFriends = myFriends; }

    /**
     * add convenience method
     */
    public void addFriend(Facebook myFriendFacebook) {
        myFriends.add(new MyFriends(this, myFriendFacebook));
    }

}
public class MyFriends {

    private MyFriendsId myFriendId;
    public MyFriendsId getmyFriendId(){ return this.myFriendId; }
    public void setmyFriendId(MyFriendsId myFriendId){ this.myFriendId = myFriendId; }

    private Facebook me;
    public Facebook getme() { return this.me; }
    public void setme(Facebook me){ this.me = me; }

    private Facebook myFriend;
    public Facebook getmyFriend() { return this.myFriend; }
    public void setmyFriend(Facebook friend) { this.myFriend = friend; }

    public MyFriends() {}
    public MyFriends(Facebook meFacebook, Facebook myFriendFacebook){
        this.me = meFacebook ;
        this.myFriend = myFriendFacebook;

        this.myFriendId = new MyFriendsId(meFacebook.getIdAsMutableLong(), myFriendFacebook.getIdAsMutableLong());
    }

    public static class MyFriendsId implements Serializable {

        private MutableLong meId = new MutableLong();
        public Long getMeId() { return this.meId.longValue(); }
        public void setMeId(Long id) { this.meId.setValue(id); }

        private MutableLong myFriendId = new MutableLong();
        public Long getMyFriendId(){ return this.myFriendId.longValue(); }
        public void setMyFriendId(Long id) { this.myFriendId.setValue(id); }

        public MyFriendsId() {}
        public MyFriendsId(MutableLong meId, MutableLong myFriendId) {
            this.meId = meId;
            this.myFriendId = myFriendId;
        }

        @Override
        public boolean equals(Object o) {
            if (!(o instanceof MyFriendsId))
                return false;

            MyFriendsId other = (MyFriendsId) o;
            return new EqualsBuilder()
                       .append(getMeId(), other.getMeId())
                       .append(getMyFriendId(), getMyFriendId())
                       .isEquals();
        }

        @Override
        public int hashCode() {
            return new HashCodeBuilder()
                       .append(getMeId())
                       .append(getMyFriendId())
                       .hashCode();
        }

    }
}
<hibernate-mapping package="br.com._3845772.model.domain">
    <class name="User">
        <id name="id">
            <generator class="native"/>
        </id>
        <many-to-one cascade="all" class="Facebook" name="facebook"/>
    </class>
    <class name="Facebook">
        <id name="id">
            <generator class="native"/>
        </id>
        <bag cascade="all" name="myFriends">
            <key column="ME_FACEBOOK_ID" update="false"/>
            <one-to-many class="MyFriends"/>
        </bag>
    </class>
    <class name="MyFriends">
        <composite-id class="MyFriends$MyFriendsId" name="myFriendId">
            <key-property column="ME_FACEBOOK_ID" name="meId"/>
            <key-property column="MY_FRIEND_FACEBOOK_ID" name="myFriendId"/>
        </composite-id>
        <many-to-one class="Facebook" column="ME_FACEBOOK_ID" insert="false" name="me" update="false"/>
        <many-to-one class="Facebook" column="MY_FRIEND_FACEBOOK_ID" insert="false" name="myFriend" update="false"/>
    </class>
</hibernate-mapping>
Facebook meFacebook = new Facebook();
Facebook myFriendFacebook = new Facebook();

meFacebook.addFriend(myFriendFacebook);

Session session = sessionFactory.openSession();
session.beginTransaction();

session.save(myFriendFacebook);
session.save(meFacebook);

session.getTransaction().commit();
session.close();
Hibernate: insert into Facebook values ( )
Hibernate: insert into Facebook values ( )
Hibernate: select myfriends_.ME_FACEBOOK_ID, myfriends_.MY_FRIEND_FACEBOOK_ID from MyFriends myfriends_ where myfriends_.ME_FACEBOOK_ID=? and myfriends_.MY_FRIEND_FACEBOOK_ID=?
Hibernate: insert into MyFriends (ME_FACEBOOK_ID, MY_FRIEND_FACEBOOK_ID) values (?, ?)