Hibernate 4映射对象的组合

时间:2016-05-31 09:28:06

标签: java hibernate jpa

现有数据库包含下表

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;
    }

}

1 个答案:

答案 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字段中删除@ColumnMembershipsPK注释。

@Getter
@Setter
@EqualsAndHashCode
@ToString
public static class MembershipsPK implements Serializable {

    private long user;

    private long group;

}