在使用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
答案 0 :(得分:0)
我认为您需要在实体中指定列名称。哪一个映射到哪一列。例如:
@Column(name="user-name");
private String userName;
对于每个列以及实体中相应的字段