tra*_*ian 2 orm hibernate jpa legacy-database composite-primary-key
我们正在尝试将Hibernate与一个使用大量复合键的数据库一起使用,这让我们感到非常头疼.不幸的是,我们无法更改架构,因此我们必须在字段之间进行大量额外的映射.我们仅限于使用JPA 1.0和Hibernate 3.3.
到目前为止,我们遇到的最大问题是使用2个值的复合键在两个实体之间进行一对一关联,其中表对这些列具有不同的名称(DB具有命名约定每列的特定于表的前缀.)
每当我们执行查询时,都会遇到以下异常:
Caused by: org.hibernate.TypeMismatchException Provided id of the wrong type for class com.business.entity.InvestorIssuerEmailEntity.
Expected: class com.business.entity.InvestorIssuerEmailEntityPK, got class com.business.entity.InvestorIssuerEntityPK;
Run Code Online (Sandbox Code Playgroud)
这些表的两个类InvestorIssuerEntity和InvestorIssuerEmailEntity具有可选的@OneToOne关联(在某些情况下,InvestorIssuer在InvestorIssuerEmail中没有匹配的记录):
@IdClass(InvestorIssuerEntityPK.class)
@Table(name = "T090_INVESTOR_ISSUER")
@Entity
InvestorIssuerEntity
@Column(name = "T090_091_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T090_102_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
(other fields omitted)
@OneToOne(optional = true)
@JoinColumns(value = {
@JoinColumn(name="T090_091_INVESTOR_ID", referencedColumnName = "T284_INVESTOR_ID", nullable = false, insertable = false, updatable = false),
@JoinColumn(name = "T090_102_ISSUER_ID", referencedColumnName = "T284_ISSUER_ID", nullable = false, insertable = false, updatable = false)
})
@NotFound(action = NotFoundAction.IGNORE)
private InvestorIssuerEmailEntity investorIssuerEmail;
...
InvestorIssuerEntityPK
@Id
@Column(name = "T090_091_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
private Long investorId;
@Id
@Column(name = "T090_102_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
private Long issuerId;
...
@IdClass(InvestorIssuerEmailEntityPK.class)
@Table(name = "T284_INVESTOR_ISSUER_EMAIL")
@Entity
InvestorIssuerEmailEntity
@Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T284_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
...
InvestorIssuerEmailEntityPK
@Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long investorId;
@Column(name = "T284_ISSUER_ID", nullable = false, insertable = true,
updatable = true, length = 18, precision = 0)
@Id
private Long issuerId;
Run Code Online (Sandbox Code Playgroud)
我试图通过对两个实体使用与@EmbeddableId相同的类来解决Type Mismatch问题,然后使用@AttributeOverrides,如下所示:
@Id
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "investorId",
column = @Column(name = "T284_INVESTOR_ID", nullable = false, insertable = true, updatable = true, length = 18, precision = 0)),
@AttributeOverride(name = "issuerId",
column = @Column(name = "T284_ISSUER_ID", nullable = false, insertable = true, updatable = true, length = 18, precision = 0))
})
private InvestorIssuerId investorIssuerId;
Run Code Online (Sandbox Code Playgroud)
我只对这两个实体进行了更改,仍然对其他实体使用@IdClass方法(是否仅为您的实体使用@IdClass或@EmbeddableId,而不是两者?)
我们最终得到了其他问题,例如"实体映射中的重复列",所以我们已经恢复了这种方法,看看是否还有其他解决方法.
有没有人有任何解决方案来解决这个问题?我查看了StackOverflow,但没有遇到协会中使用的复合键具有不同名称的任何情况.
注意: 即使在尝试下面的建议之后,我们仍会收到此错误:org.hibernate.MappingException:实体映射中的重复列:com.business.entity.InvestorIssuerEntity列:T090_091_INVESTOR_ID(应使用insert ="false"update = "假")
我甚至从InvestorIssuerEntity删除了所有关联,但仍然遇到了同样的问题.当我删除复合键类中的@Column注释时,错误才消失.当然,查询不起作用,因为没有映射到投资者ID!我不明白Hibernate在哪里找到"映射中的重复列",因为除了复合键之外,我已经删除了除T090_091_INVESTOR_ID之外的所有其他内容.
我们在InvestorIssuerEntity中有其他关联,它们在相同的主键上进行连接,但关联的实体在其组合键中也有其他列.一旦你使用@EmbeddedId,你应该将它们用于所有实体吗?我们仍然将@IdClass用于其他类.但那又如何在任何地方引起"重复列"呢?
看来我为你的案子找到了一个有效的解决方案:
@Entity
public class InvestorIssuerEntity {
@EmbeddedId
private InvestorIssuerEntityPK investorIssuerEntityPK;
@OneToOne(optional=true, mappedBy="investorIssuerEntity")
private InvestorIssuerEmailEntity investorIssuerEmailEntity;
}
@Entity
public class InvestorIssuerEmailEntity {
@EmbeddedId @AttributeOverrides({
@AttributeOverride(name="investorId", column=@Column(name="T02_INV_ID")),
@AttributeOverride(name="issuerId", column=@Column(name="T02_ISS_ID"))
})
private InvestorIssuerEntityPK investorIssuerEntityPK;
@OneToOne(optional=true) @PrimaryKeyJoinColumns({
@PrimaryKeyJoinColumn(name="T02_ISS_ID", referencedColumnName="T01_ISS_ID"),
@PrimaryKeyJoinColumn(name="T02_INV_ID", referencedColumnName="T01_INV_ID")
})
private InvestorIssuerEntity investorIssuerEntity;
}
@Embeddable
public class InvestorIssuerEntityPK implements Serializable {
private static final long serialVersionUID = -1176248537673293674L;
@Column(name="T01_INV_ID")
private Long investorId;
@Column(name="T01_ISS_ID")
private Long issuerId;
}
Run Code Online (Sandbox Code Playgroud)
它生成以下DDL,这似乎是您正在寻找的:
create table InvestorIssuerEmailEntity (
T02_INV_ID bigint not null,
T02_ISS_ID bigint not null,
primary key (T02_INV_ID, T02_ISS_ID)
)
create table InvestorIssuerEntity (
T01_INV_ID bigint not null,
T01_ISS_ID bigint not null,
primary key (T01_INV_ID, T01_ISS_ID)
)
alter table InvestorIssuerEmailEntity
add constraint FKC2FBCC4E1E26612E
foreign key (T02_INV_ID, T02_ISS_ID)
references InvestorIssuerEntity
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11673 次 |
| 最近记录: |