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