gpt4 book ai didi

java - 无法使用@MapsId 和@Id 进行查询,但仅适用于@Id

转载 作者:行者123 更新时间:2023-11-30 09:34:48 24 4
gpt4 key购买 nike

我有 2 个实体,比如 Car 和 Engine(只是示例名称,但逻辑是相同的)。

@Entity
public class Car {
@Id
private Long id;

@OneToOne(mappedBy = "car", cascade = Cascade.ALL)
private Engine engine;
...


}

@Entity
public class Engine {
@Id
private Long id; // 1

@MapsId // 2
@OneToOne
@JoinColumn(name = "car_id") // join column is optional here
private Car car;
...
}

那么,我会:

em.save(car); // successfully saved, data is in the database, but (see below)
TypedQuery<Engine> query = em.createQuery("select engine from Engine engine where engine.car = :car", Engine.class)
query.setParameter("car", car);

query.getResultList();

抛出异常:

ERROR [main] (JDBCExceptionReporter.java:234) - No value specified for parameter 1.
WARN [main] (TestContextManager.java:409) - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@17e5cbd] to process 'after' execution for test: method , exception [org.springframework.orm.jpa.JpaSystemException: org.hibernate.exception.DataException: could not execute query; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not execute query]

但是,如果我将 Engine 实体更改为在汽车实例本身上只有 @Id(删除//1 并将//2 更改为 @Id),它会起作用。

根据 JPA 文档,它应该以相同的方式工作(至少我预期如此)。

我的环境:PostgreSQL 9、Spring framework 3.1、Hibernate 3.6.8.Final、Tomcat 7(JPA 支持由 Spring instrumentation 添加)。

更新:我已经尝试使用 EclipseLink 进行这两种映射并且它有效。所以问题可能出在 Hibernate 的某个地方。仍然不知道如何强制它与 Hibernate 一起工作。

最佳答案

我假设您正在基于此在 Engine 类中使用复合键的 Id。@MapsId 仅在您拥有 @EmbeddedId 时使用,如下例所示。

If the dependent entity uses an embedded id to represent its primary key, the attribute in the embedded id corresponding to the relationship attribute must be of the same type as the primary key of the parent entity and must be designated by the MapsId annotation applied to the relationship attribute.

@Embeddable
public class DependentId {
String name;
long empPK; // corresponds to PK type of Employee
}
@Entity
public class Dependent {
@EmbeddedId DependentId id;
...
// id attribute mapped by join column default
@MapsId("empPK") // maps empPK attribute of embedded id
@ManyToOne Employee emp;
}

根据您的代码示例。

 @Embeddable
public class NewKey{
private Long id;
private Long carId; // corresponds to PK type of Employee
}

@Entity
public class Car {
@Id
private Long id;

@OneToOne(mappedBy = "car", cascade = Cascade.ALL)
private Engine engine;
}

@Entity
public class Engine {
@EmbeddedId NewKey id;

@MapsId("carId") // 2
@OneToOne
@JoinColumn(name = "car_id") // join column is optional here
private Car car;
...
}

假设您尝试使用关系的父键作为您的新键

If the dependent entity has a single primary key attribute (i.e, the relationship attribute or an attribute that corresponds to the relationship attribute) and the primary key of the parent entity is a simple primary key, the primary key of the dependent entity is a simple primary key of the same type as that of the parent entity (and neither EmbeddedId nor IdClass is specified). In this case, either (1) the relationship attribute is annotated Id, or (2) a separate Id attribute is specified and the relationship attribute is annotated MapsId (and the value element of the MapsId annotation is not specified).

在那种情况下,您的配置应该可以正常工作,如下所示,该配置已使用 hibernate 4.3 进行测试

enter image description here

关于java - 无法使用@MapsId 和@Id 进行查询,但仅适用于@Id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11698488/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com