Hibernate会将地图映射到列表中

时间:2013-12-04 04:53:58

标签: hibernate list collections map many-to-many

在使用Map和List时,我在设计两个实体之间的多对多关系时遇到问题。

@Entity
@Table(name = "GROUPS_MEM")
public class Group {
  @Id
  private int id;
  private String groupName;
  @ManyToMany(mappedBy = "memberOfGroup",targetEntity = com.expenses.domain.User.class,cascade = CascadeType.ALL)

  private Map<User, MemberProps> memberMap;

  public Group() {
    memberMap=new HashMap<User, MemberProps>();
  }

  public Group(int id, String groupName, User owner) {
    this.id = id;
    this.groupName = groupName;
    memberMap = new HashMap<User, MemberProps>();
    memberMap.put(owner, MemberProps.ADMIN);
    owner.addGroup(this);
  }

  public void addMember(User member) {
    memberMap.put(member, MemberProps.PASSIVE);
  }


 @Override
 public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Group group = (Group) o;

    if (id != group.id) return false;
    if (!groupName.equals(group.groupName)) return false;

    return true;
 }

 @Override
 public int hashCode() {
    int result = id;
    result = 31 * result + groupName.hashCode();
    return result;
 }

 public int getId() {
    return id;
 }

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

 public String getGroupName() {
    return groupName;
  }

 public void setGroupName(String groupName) {
    this.groupName = groupName;
 }

 public Map<User, MemberProps> getMemberMap() {
    return memberMap;
 }

 public void setMemberMap(Map<User, MemberProps> memberMap) {
    this.memberMap = memberMap;
 }
}

用户

@Entity
@Table(name = "USER")
public class User {

 @Id
 private int id;

 private String userName;

 private String email;

 private boolean isActive;

 @ManyToMany
 @JoinTable(name="MEMBER",joinColumns = {@JoinColumn(name = "USER_ID")},inverseJoinColumns = {@JoinColumn(name = "GROUP_ID")})
 private List<Group> memberOfGroup;

 public User() {
    memberOfGroup=new ArrayList<Group>();
 }

 public User(int id, String userName, String email) {
    this.id = id;
    this.userName = userName;
    this.email = email;
    memberOfGroup = new ArrayList<Group>();
    isActive=false;
 }


 public void addGroup(Group group) {
    memberOfGroup.add(group);
 }

  public void setActive(boolean active){
    isActive=active;
  }

  public Group getGroup(String groupName) {
    for (Group group:memberOfGroup){
        if (group.getGroupName().equals(groupName))
            return group;
    }
    return null;
 }


 public String getEmail() {
    return email;
 }

 @Override
 public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    User user = (User) o;

    if (id != user.id) return false;
    if (!email.equals(user.email)) return false;

    return true;
 }

 @Override
 public int hashCode() {
    int result = id;
    result = 31 * result + email.hashCode();
    return result;
 }

 public int getId() {
    return id;
 }

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

 public String getUserName() {
    return userName;
 }

 public void setUserName(String userName) {
    this.userName = userName;
 }

 public void setEmail(String email) {
    this.email = email;
 }

 public boolean isActive() {
    return isActive;
 }

 public List<Group> getMemberOfGroup() {
    return memberOfGroup;
 }

 public void setMemberOfGroup(List<Group> memberOfGroup) {
    this.memberOfGroup = memberOfGroup;
 }
}

你能否验证一下这个映射。我收到以下异常: 无法将字段com.expenses.domain.User.id设置为com.expenses.domain.MemberProps

org.springframework.orm.hibernate3.HibernateSystemException: could not get a field value by reflection getter of com.expenses.domain.User.id; nested exception is org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.expenses.domain.User.id
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:104)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at com.sun.proxy.$Proxy27.save(Unknown Source)
    at com.expenses.repository.UserDaoTest.testCreateGroup(UserDaoTest.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.expenses.domain.User.id
    at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:62)
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:344)
    at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4537)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:129)
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:924)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:906)
    at org.hibernate.engine.spi.CascadingAction$6.cascade(CascadingAction.java:288)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:388)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:331)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:418)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:358)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:334)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:209)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:166)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:449)
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:220)
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:282)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:898)
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:902)
    at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:889)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
    at com.sun.proxy.$Proxy24.merge(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:360)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:333)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:318)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    ... 39 more
Caused by: java.lang.IllegalArgumentException: Can not set int field com.expenses.domain.User.id to com.expenses.domain.MemberProps
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:38)
    at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:18)
    at java.lang.reflect.Field.get(Field.java:358)
    at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:59)
    ... 79 more

1 个答案:

答案 0 :(得分:0)

我认为您需要在实体中指定列名称。哪一个映射到哪一列。例如:

@Column(name="user-name");
private String userName;

对于每个列以及实体中相应的字段