Java 自定义联接表使Spring数据抛出IllegalArgumentException:预期的id属性类型

Java 自定义联接表使Spring数据抛出IllegalArgumentException:预期的id属性类型,java,spring,spring-data,Java,Spring,Spring Data,我有三张桌子帐户,事件和帐户事件关系 最后一个可用作用户和事件之间的正常多对多关系,但有一个小而重要的例外,即它允许用户在关系上拥有属性。 (假设一个事件有许多用户,但有些用户也可以是事件的主持人。帐户事件关系的布尔属性表明了这一点。) 如果我编写自己的DAO或使用普通的JDBC和SQL,我就可以完美地完成这项工作,但是使用Spring数据,它会失败得很厉害。此外,错误信息令人困惑 Caused by: java.lang.IllegalArgumentException: Expected i

我有三张桌子<代码>帐户,
事件
帐户事件关系

最后一个可用作用户和事件之间的正常多对多关系,但有一个小而重要的例外,即它允许用户在关系上拥有属性。
(假设一个事件有许多用户,但有些用户也可以是事件的主持人。帐户事件关系的布尔属性表明了这一点。)

如果我编写自己的DAO或使用普通的JDBC和SQL,我就可以完美地完成这项工作,但是使用Spring数据,它会失败得很厉害。此外,错误信息令人困惑

Caused by: java.lang.IllegalArgumentException: Expected id attribute type [class lan.localhost.entity.EventAccountRelationPk] on the existing id attribute [SingularAttributeImpl[EntityTypeImpl@1443927423:Account [ javaType: class lan.localhost.entity.Account descriptor: RelationalDescriptor(lan.localhost.entity.Account --> [DatabaseTable(user_account)]), mappings: 4],org.eclipse.persistence.mappings.ManyToOneMapping[account]]] on the identifiable type [EntityTypeImpl@1204999057:EventAccountRelation [ javaType: class lan.localhost.entity.EventAccountRelation descriptor: RelationalDescriptor(lan.localhost.entity.EventAccountRelation --> [DatabaseTable(event_account_rel)]), mappings: 4]] but found attribute type [class lan.localhost.entity.Account].
  at org.eclipse.persistence.internal.jpa.metamodel.IdentifiableTypeImpl.getId(IdentifiableTypeImpl.java:200)
  at org.springframework.data.jpa.repository.support.JpaMetamodelEntityInformation$IdMetadata.<init>(JpaMetamodelEntityInformation.java:212)
  ...
事件类

@Entity
@Table(name = "meeting")

public class Event {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  ...

  @OneToMany(mappedBy = "event")
  private List<EventAccountRelation> accounts;

  ...

}
最后是复合密钥

@Embeddable
public class EventAccountRelationPk {

  private Long eventId;

  private Long accountId;

  ...

}
我在Java1.6上使用Spring3.1.4、SpringData1.4.5和EclipseLink 2.5.1
当然,我可以尝试更高版本,但不幸的是,我仅限于此环境/

有两种方法可以解决这个问题

(1) 使用IdClass而不是EmbeddedId

@Entity
@Table(name = "event_account_rel")
@IdClass(EventAccountRelationPk.class)
public class EventAccountRelation {

  @Id
  private Long eventId;

  @Id
  private Long accountId;

  @MapsId("eventId")
  @ManyToOne(optional = false)
  @JoinColumn(name = "event_id", nullable = false, updatable = false)
  private Event event;

  @MapsId("accountId")
  @ManyToOne(optional = false)
  @JoinColumn(name = "account_id", nullable = false, updatable = false)
  private Account account;

  @Column(name = "moderator", nullable = false)
  private Boolean moderator = Boolean.FALSE;

  ...

}
(2) 在EventAccountRelation表中添加主键字段和其他唯一键

@Entity
@Table(name = "event_account_rel",
       uniqueConstraints = {@UniqueConstraint={"EVENT_ID","ACCOUNT_ID"}})
public class EventAccountRelation {

  @Id
  private Long id;

  @ManyToOne(optional = false)
  @JoinColumn(name = "event_id")
  private Event event;

  @ManyToOne(optional = false)
  @JoinColumn(name = "account_id")
  private Account account;

  @Column(name = "moderator", nullable = false)
  private Boolean moderator = Boolean.FALSE;

  ...

}
为了比较这两种解决方案,1st可以使用IdClass使用Repository接口中提供的方法对关系表进行CRUD,但有一点是,在设置account时,您应该注意设置account\u id


第二个解决方案需要您编写查询,通过事件id和帐户id的组合来查找EventAccountRelation。

有关于该问题的消息吗?
@Entity
@Table(name = "event_account_rel")
@IdClass(EventAccountRelationPk.class)
public class EventAccountRelation {

  @Id
  private Long eventId;

  @Id
  private Long accountId;

  @MapsId("eventId")
  @ManyToOne(optional = false)
  @JoinColumn(name = "event_id", nullable = false, updatable = false)
  private Event event;

  @MapsId("accountId")
  @ManyToOne(optional = false)
  @JoinColumn(name = "account_id", nullable = false, updatable = false)
  private Account account;

  @Column(name = "moderator", nullable = false)
  private Boolean moderator = Boolean.FALSE;

  ...

}
@Entity
@Table(name = "event_account_rel",
       uniqueConstraints = {@UniqueConstraint={"EVENT_ID","ACCOUNT_ID"}})
public class EventAccountRelation {

  @Id
  private Long id;

  @ManyToOne(optional = false)
  @JoinColumn(name = "event_id")
  private Event event;

  @ManyToOne(optional = false)
  @JoinColumn(name = "account_id")
  private Account account;

  @Column(name = "moderator", nullable = false)
  private Boolean moderator = Boolean.FALSE;

  ...

}