我希望在我的实体中有一个由两列(属性)组成的复合主键,同时有一列是外键。
我写了这样的东西,但不知道它是否有效,因为外键在IntelliJ数据源中被标记为生成值
@Entity
@Table(name = "service_point")
@Access(AccessType.PROPERTY)
@IdClass(ServicePointId.class)
public class ServicePoint {
private Long providerId;
private Integer servicePointNumber;
private Provider provider;
@Id
@Basic(optional = false)
@Column(name = "provider_id", nullable = false, insertable = false,
updatable = false, columnDefinition = "BIGINT UNSIGNED")
public Long getProviderId() {
return providerId;
}
public void setProviderId(Long providerId) {
this.providerId = providerId;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "service_point_no", nullable = false, columnDefinition = "BIGINT UNSIGNED")
public Integer getServicePointNumber() {
return servicePointNumber;
}
public void setServicePointNumber(Integer servicePointNumber) {
this.servicePointNumber = servicePointNumber;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "provider_id")
public Provider getProvider() {
return provider;
}
public void setProvider(Provider provider) {
this.provider = provider;
}
}
更新:
我对Brian Vosburgh进行了测试,效果良好:
transaction.begin();
em.persist(provider);
ServicePoint servicePoint = new ServicePoint(provider, 1);
em.persist(servicePoint);
transaction.commit();
ServicePoint servicePoint2 = em.find(ServicePoint.class,
new ServicePointId(provider.getUserId(), servicePoint.getServicePointNumber()));
assertTrue("Service point provider id and Provider provider id should be the same.",
servicePoint2.getProvider().getUserId() == provider.getUserId());
assertNotNull("Service point number can not be null", servicePoint2.getServicePointNumber());
assertEquals(servicePoint2.getProvider(), provider);
transaction.begin();
em.remove(servicePoint);
em.remove(provider);
transaction.commit();
更新2 -下一个关系复合PK (3列)中的新问题,其中2列是复合FK。我一直试图类似下面的解决方案,但无法理解如何编写ServicePointPhotoId @IdClass
制作复合主键的最佳方式是将@EmbeddedId与相应的< code > @ embedded 类一起使用。
在我们的400多个数据库实体中,大约有135个使用Embedded ID类来实现复合(多字段)主键。
SO上有很多问题和答案,并附有这些示例。
去掉< code>providerId字段及其对应的getter和setter。将< code>@Id批注添加到< code>getProvider()中。如下定义< code>IdClass:
public class ServicePointId {
private Long provider;
private Integer servicePointNumber;
public Integer getProvider() {
return provider;
}
public void setProvider(Integer provider) {
this.provider = provider;
}
public Integer getServicePointNumber() {
return servicePointNumber;
}
public void setServicePointNumber(Integer servicePointNumber) {
this.servicePointNumber = servicePointNumber;
}
}
请注意,IdClass
中的属性名称与Entity
(即提供程序
)中的属性名称匹配,但属性的类型不同。在IdClass
中,属性类型必须与Provider
的Id
属性的类型匹配。
这在JPA 2.1规范的第2.4.1节中进行了讨论。
更新2建议:
public class ServicePointPhotoId {
public ServicePointId servicePoint;
public Long photoId;
}
@Entity
@IdClass(ServicePointPhotoId.class)
@Table(name="service_point_photo")
public class ServicePointPhoto {
@Id
@ManyToOne
@JoinColumns({
@JoinColumn(name="provider_id", referencedColumnName="provider_id"),
@JoinColumn(name="service_point_no", referencedColumnName="service_point_no")
})
private ServicePoint servicePoint;
@Id
@Column(name="photo_id")
private Long photoId;
}
注意属性名称必须匹配(即servicePoint
);但是IdClass
属性的类型必须匹配引用的Entity
的IdClass
(即ServicePointId
)。
我使用过字段批注,但您可以将这些批注转换为属性批注。
同样:JPA 2.1规范在2.4.1.3部分有一个这种关系的例子。
在我的jpa映射中,我试图将带有一个主键的父类映射到带有复合键的子类,但似乎插入了错误的表,它已经生成了2个表,但不幸的是我没有绑定外键(policy_value_summary_id) 我试图用策略值(子类)保存策略摘要值(父),如下所示 下面是输出给我的错误
我有一个复合主键,其中一个键为空。实体中必须存在哪些注释,以便我可以使用此类JPA获取数据: 我尝试使用IdClass Annotation和EmbeddedId Annotation,但出现异常: 例如,使用了数据,但在实际项目中使用了类似的数据,因此无法用值替换null。
问题内容: 我的JPA模型中有以下类(省略了getters,setters和无关字段): 我需要定义一个类,使得当从所述类生成DDL时,相应的表的主键被由密钥和。我尝试了以下方法: 但这会为表生成以下内容: 请注意,和都是可为空的,当我尝试将DDL加载到SQL Server时会导致以下错误 无法在表“ PRICE”中的可为空的列上定义PRIMARY KEY约束 我不明白为什么这些可以为空,因为在域
我在使用复合主键的hibernate实体集时遇到了问题。 我们的应用程序中有一个概念“Target”。目标id应该是其他三个表(实体)主id的组合。目标也有一个int标记。员工应该有一系列目标。SQL如下所示: 这个SQL工作正常,它允许我每个role_id(员工)多个目标,只要应用程序和项目分类不同。 这是目标ID类 这是目标类 这是employee类,我想在其中为每个员工存储一组目标。 通过h
问题内容: 我在玩redis,想重新创建我在mysql中拥有的表。这是我用来创建它的mysql命令: 我的数据基本上是两列,每一列都有彼此唯一的数字,例如: 当我在redis上玩耍并尝试创建上述数据时,“ 3”键只会不断被我输入的最后一个值取代。有没有办法使该版本在Redis中工作? 问题答案: 使用Redis更好地表示您的数据的模型是使用value1对象的简单集合(每个key1对象一个)。按照示
我的数据库是: 我们可以在Table2中为Table1中的1设置多行。 我的TABLE1实体是: 我的Table1Id类是: 我的TABLE2实体是: 我的Table2Id类是: 当我尝试启动我的tomcat时,我有以下错误: 我尝试使用引用列,主键连接列和许多其他东西,但是通过在互联网上阅读它,它可以解决数据库建模问题。我认为问题是主键和外键在2个表中具有相同的名称,但我可能是错的......我