现有数据库包含下表
CREATE TABLE `memberships` (
`group_id` int(11) NOT NULL default '0',
`user_id` int(11) NOT NULL default '0',
`status` int(11) default NULL,
PRIMARY KEY (`group_id`,`user_id`)
)
映射到基本ID /名称组和用户表
如何在Hibernate上映射它?
public class Memberships {
private User user;
private Group group;
private Integer status;
... getters/setters
}
我想要像上面那样
我一直在尝试@IdClass
和@Embeddable
,但没有成功
有什么想法吗?
Java 8,Hibernate 4
更新:关于制图的工人阶级
@Entity
@Table(name = "memberships")
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Accessors(chain = true)
@IdClass(Memberships.MembershipsPK.class)
public class Memberships implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Id
@ManyToOne
@JoinColumn(name = "group_id")
private Group group;
@Column(name = "status")
private Integer status;
@Getter
@Setter
@EqualsAndHashCode
@ToString
public static class MembershipsPK implements Serializable {
@Id
@Column(name = "user_id")
private long user;
@Id
@Column(name = "group_id")
private long group;
}
}
我正在使用龙目岛项目获取吸气剂和放大器设定器
JPA存储库:
public interface MembershipsRepository extends JpaRepository<Memberships, Memberships.MembershipsPK>, RevisionRepository<Memberships, Memberships.MembershipsPK, Integer> {
}
User user = userBo.findOne(1l);
Group group = new Group().setApplication(application).setName("teste");
groupService.save(group);
Memberships memberships = new Memberships().setGroup(group).setUser(user).setStatus(1);
membershipsService.save(memberships);
例外:
Exception in thread "main" org.springframework.orm.jpa.JpaSystemException: could not set a field value by reflection setter of com.lotjm.domain.Memberships$MembershipsPK.user; nested exception is org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.lotjm.domain.Memberships$MembershipsPK.user
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:314)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:436)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy78.save(Unknown Source)
at com.lotjm.service.impl.GenericRepositoryServiceImpl.save(GenericRepositoryServiceImpl.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
at com.sun.proxy.$Proxy79.save(Unknown Source)
at com.lotjm.util.HibernateReadingTesting.main(HibernateReadingTesting.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.lotjm.domain.Memberships$MembershipsPK.user
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:134)
at org.hibernate.tuple.component.AbstractComponentTuplizer.setPropertyValues(AbstractComponentTuplizer.java:93)
at org.hibernate.tuple.component.PojoComponentTuplizer.setPropertyValues(PojoComponentTuplizer.java:116)
at org.hibernate.type.ComponentType.setPropertyValues(ComponentType.java:439)
at org.hibernate.tuple.entity.AbstractEntityTuplizer$NormalMappedIdentifierValueMarshaller.getIdentifier(AbstractEntityTuplizer.java:437)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:342)
at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:164)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:294)
at com.sun.proxy.$Proxy62.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:508)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 27 more
Caused by: java.lang.IllegalArgumentException: Can not set long field com.lotjm.domain.Memberships$MembershipsPK.user to com.lotjm.domain.User
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeLongFieldAccessorImpl.set(UnsafeLongFieldAccessorImpl.java:102)
at java.lang.reflect.Field.set(Field.java:764)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:122)
... 61 more
替代解决方案:
@Entity
@Table(name = "memberships")
@Getter
@Setter
@EqualsAndHashCode
@ToString
@Accessors(chain = true)
public class Memberships implements Serializable {
@EmbeddedId
@JoinColumns({
@JoinColumn(name = "user_id", referencedColumnName = "user_id"),
@JoinColumn(name = "group_id", referencedColumnName = "group_id")
})
private MembershipsPK id = new MembershipsPK();
public Memberships setGroup(Group group) {
id.setGroup(group);
return this;
}
public Memberships setUser(User user) {
id.setUser(user);
return this;
}
@Column(name = "status")
private Integer status;
@Embeddable
@Getter
@Setter
@EqualsAndHashCode
public static class MembershipsPK implements Serializable {
@ManyToOne(targetEntity = User.class)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(targetEntity = Group.class)
@JoinColumn(name = "group_id")
private Group group;
}
}
答案 0 :(得分:1)
@Entity
@Table(name = "memberships")
public class Memberships implements Serializable {
@Id
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Id
@ManyToOne
@JoinColumn(name = "group_id")
private Group group;
@Column(name = "status")
private Integer status;
}
此映射为H2
数据库生成此SQL(我使用Long
表示ids)
create table memberships (
status integer,
user_id bigint not null,
group_id bigint not null,
primary key (user_id, group_id)
)
<强>更新强>
解决问题:
org.hibernate.PropertyAccessException: could not set a field value by reflection setter of com.lotjm.domain.Memberships$MembershipsPK.user
只需从@Id
字段中删除@Column
和MembershipsPK
注释。
@Getter
@Setter
@EqualsAndHashCode
@ToString
public static class MembershipsPK implements Serializable {
private long user;
private long group;
}