有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate 4对象的映射组合

现有数据库包含下表

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,但没有成功

有什么想法吗

Java8,Hibernate4

更新:映射上的工作类

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


    }

}

我正在使用Lombok项目获取getter&;塞特

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) 个答案

  1. # 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作为ID)

    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

    只需从MembershipsPK的字段中删除@Id@Column注释

    @Getter
    @Setter
    @EqualsAndHashCode
    @ToString
    public static class MembershipsPK implements Serializable {
    
        private long user;
    
        private long group;
    
    }