簡體   English   中英

hibernate:通過xml進行多對一映射

[英]hibernate: many-to-one mapping via xml

我面臨一些困難,試圖為兩個表建立多對一的關系:用戶和訂閱者

(這里的主要思想是用戶可以保存對其他用戶的引用)

USERS表包含theese字段:| USER_ID | USER_PASSWORD | 雖然SUBSCRIBERS同意:| SUBSCRIBER_ID | USER_ID |,其中:1。兩個字段都包含在主鍵2中。兩個字段都是引用USERS的USER_ID的外鍵。 將User保存到數據庫時沒有異常。 但是當我調用代碼時:(在DB中創建2個用戶之后 - 使用first_u USER_ID和second_u USER_ID)

hibernate_session.beginTransaction();
subscr = new Subscription("first_u", "second_u");
hibernate_session.save(subscr);
hibernate_session.getTransaction().commit();

我得到這個例外:

org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of player.database.hibernate.entities.User.userID
    org.hibernate.property.access.spi.GetterMethodImpl.get(GetterMethodImpl.java:64)
    org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:223)
    org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4601)
    org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:4313)
    org.hibernate.engine.internal.ForeignKeys.isTransient(ForeignKeys.java:226)
    org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:276)
    org.hibernate.type.EntityType.getIdentifier(EntityType.java:455)
    org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:153)
    org.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:343)
    org.hibernate.persister.entity.AbstractEntityPersister.dehydrateId(AbstractEntityPersister.java:2636)
    org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2604)
    org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2883)
    org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3386)
    org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
    org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
    org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
    org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
    org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
    org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
    org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
    org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
    org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
    org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
    player.debugg.FriendRegistration.doGet(FriendRegistration.java:39)
    player.debugg.FriendRegistration.doPost(FriendRegistration.java:20)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
java.lang.IllegalArgumentException: object is not an instance of declaring class

以下是實體類和hbm.xml的代碼snipets:

package player.database.hibernate.entities; 
public class User
{

    private String userID;
    private String userPassword;


    public User()
    {

    }

    public User(String login, String password)
    {
        this.setUserID(login);
        this.setUserPassword(password);
    }

    public void setUserID(String id)
    {
        if((id!=null)&&(!id.equals("")))
            this.userID = id;
        else throw new IllegalArgumentException("User ID setter exception: empty or null");
    }

    public void setUserPassword(String password)
    {
        if((password!=null)&&(!password.equals("")))
            this.userPassword = password;
        else throw new IllegalArgumentException("User password setter exception: empty or null");
    }

    public String getUserID()
    {
        return this.userID;
    }

    public String getUserPassword()
    {
        return this.userPassword;
    }
}

    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="player.database.hibernate.entities">
      <class name="User" table="USERS">
        <id name="userID" column="USER_ID">
          <generator class="assigned"></generator>
        </id>
        <property name="userPassword" column="USER_PASS"/>
      </class>

package player.database.hibernate.entities;

import java.io.Serializable;

public class Subscription implements Serializable
{
    private String subscriberID;
    private String userID;

    public Subscription()
    {
    }

    public Subscription(String subscriberID, String userID)
    {
        this.setSubscriberID(subscriberID);
        this.setUserID(userID);
    }

    public void setSubscriberID(String subscriberID) {
        if((subscriberID!=null)&&(!subscriberID.equals("")))
            this.subscriberID = subscriberID;
        else throw new IllegalArgumentException("Subscription subscriberID setter error: null or empty string");
    }

    public void setUserID(String userID) {
        if((userID!=null)&&(!userID.equals("")))
            this.userID = userID;
        else throw new IllegalArgumentException("Subscription subscriberID setter error: null or empty string");
    }

    public String getSubscriberID() {
        return subscriberID;
    }

    public String getUserID() {
        return userID;
    }


    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Subscription){
            Subscription subscription = (Subscription) obj;

            if(!subscription.getSubscriberID().equals(subscriberID)){
                return false;
            }

            if(!subscription.getUserID().equals(userID)){
                return false;
            }

            return true;
        }

        return false;
    }

    @Override
    public int hashCode() {
        return subscriberID.hashCode() + userID.hashCode();
    }

}

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="player.database.hibernate.entities">
  <class name="Subscription" table="SUBSCRIBERS">

      <composite-id>
          <key-many-to-one name="subscriberID" column="SUBSCRIBER_ID" class="User"/>
          <key-many-to-one name="userID" column="USER_ID" class="User"/>
      </composite-id>
  </class>
  </hibernate-mapping>

PS我正在使用這里描述的方式http://www.java2s.com/Tutorial/Java/0350__Hibernate/ComposedID.htm來創建一個復合鍵。 我認為它工作正常,因為它輸出theese在控制台:

Hibernate: create table SUBSCRIBERS (SUBSCRIBER_ID varchar(255) not null, USER_ID varchar(255) not null, primary key (SUBSCRIBER_ID, USER_ID))
Hibernate: create table USERS (USER_ID varchar(255) not null, USER_PASS varchar(255), primary key (USER_ID))
Hibernate: alter table SUBSCRIBERS add constraint FKnh93vk6v0ivt3a42hbaa7ffk5 foreign key (SUBSCRIBER_ID) references USERS (USER_ID)
Hibernate: alter table SUBSCRIBERS add constraint FKodh9g832cfmbqtsgtixky9j8j foreign key (USER_ID) references USERS (USER_ID)

我真的很感激這個問題的任何幫助。

您說Subscription類與User類具有多對一關聯。 我認為沒有這樣定義的關聯。 如果存在關聯,則訂閱類將具有

private User user;

public User getUser() {
    return this.user;
}

public void setUser(User user) {
    this.user= user;
}

此外,我沒有在訂閱表中看到任何映射

為了讓我的代碼工作,我將Subscription類中的Strings字段替換為User字段(當然還有getter和setter)。 我的subscription.hbm.xml更改為以下內容:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="player.database.hibernate.entities">
  <class name="Subscription" table="SUBSCRIBERS">
      <composite-id>
          <key-many-to-one name="subscriberID" class="User">
              <column name="SUBSCRIBER_ID" />
          </key-many-to-one>
          <key-many-to-one name="userID" class="User">
              <column name="USER_ID" />
          </key-many-to-one>
      </composite-id>
  </class>
  </hibernate-mapping>

有了這樣的配置,Hibernate就會按如下方式停止表:

Hibernate: create table SUBSCRIBERS (SUBSCRIBER_ID varchar(255) not null, USER_ID varchar(255) not null, primary key (SUBSCRIBER_ID, USER_ID))
Hibernate: create table USERS (USER_ID varchar(255) not null, USER_PASS varchar(255), primary key (USER_ID))
Hibernate: alter table SUBSCRIBERS add constraint FKnh93vk6v0ivt3a42hbaa7ffk5 foreign key (SUBSCRIBER_ID) references USERS (USER_ID)
Hibernate: alter table SUBSCRIBERS add constraint FKodh9g832cfmbqtsgtixky9j8j foreign key (USER_ID) references USERS (USER_ID)

這正是我想要的。 希望它對某人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM