【发布时间】:2016-04-09 12:00:13
【问题描述】:
我的超类是:
@Entity
@Table(name = "TEST_VEHICLE")
@ChangesListener
@AttributeOverride(name = "id", column = @Column(name = "VEHICLE_ID"))
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "VEHICLE_TYPE_ID", discriminatorType = DiscriminatorType.INTEGER)
public abstract class Vehicle extends ParentEntity {
@Column(name = "MAX_SPEED", nullable = false)
private Integer maxSpeed;
public Integer getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(Integer maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
子类是:
@Entity
@Table(name = "TEST_BUS")
@DiscriminatorValue("2")
public class Bus extends Vehicle {
@Column(name = "PASSENGER_NUMBER", nullable = false)
private Short passengerNumber;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FOO_OF_VEHICLE")
private Foo foo;
public Short getPassengerNumber() {
return passengerNumber;
}
public void setPassengerNumber(Short passengerNumber) {
this.passengerNumber = passengerNumber;
}
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
在标准中对Root<Vehicle> 使用foo 提取:
root.fetch("foo", JoinType.LEFT);
导致此错误:
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [foo] on this ManagedType ...
如何从子类中获取字段?
更新:
使用treat并不能解决我的问题:
Root<Bus> busRoot = builder.treat(root, Bus.class);
busRoot.fetch("foo", JoinType.INNER);
我没有收到任何错误,但 foo 尚未获取。 生成的 SQL 是:
SELECT vehicle0_.VEHICLE_ID AS VEHICLE_2_72_,
vehicle0_.ATTACHMENT_COUNT AS ATTACHME3_72_,
vehicle0_.COMMENTS AS COMMENTS4_72_,
vehicle0_.CREATE_TIMESTAMP AS CREATE_T5_72_,
vehicle0_.CREATOR_USER_ID AS CREATOR_8_72_,
vehicle0_.MODIFIER_USER_ID AS MODIFIER9_72_,
vehicle0_.UPDATE_TIMESTAMP AS UPDATE_T6_72_,
vehicle0_.MAX_SPEED AS MAX_SPEE7_72_,
vehicle0_1_.FOO_OF_VEHICLE AS FOO_OF_V3_70_,
vehicle0_1_.PASSENGER_NUMBER AS PASSENGE1_70_,
vehicle0_2_.ENGINE_TYPE AS ENGINE_T1_71_,
vehicle0_.VEHICLE_TYPE_ID AS VEHICLE_1_72_
FROM TEST_VEHICLE vehicle0_
LEFT OUTER JOIN TEST_BUS vehicle0_1_
ON vehicle0_.VEHICLE_ID=vehicle0_1_.VEHICLE_ID
LEFT OUTER JOIN TEST_CAR vehicle0_2_
ON vehicle0_.VEHICLE_ID =vehicle0_2_.VEHICLE_ID
WHERE vehicle0_.VEHICLE_ID=105
【问题讨论】:
-
车辆不一定是公共汽车;基本多态性。如果想要子类字段访问,则进行转换(处理),就像使用基本 java 一样
-
这里是 JPA 规范的摘录:` 查询的根对象是实体,其他类型可以通过导航到达。` 这意味着要么将
foo移动到Vehicle类,或者您将Bus类作为查询的根。 -
@NeilStockton 是的。绝对地。但如果是 Bus,我想获取 foo 字段。喜欢:
root.fetch("bus",JoinType.LEFT).fetch("foo", JoinType.LEFT);,但这个解决方案也不起作用。 -
作为一个基本问题,您必须使用
Discriminator列吗?如果有一个抽象基类,我会期待一个@MappedSupersclass。 -
@Nicholas 是的,在某些情况下我需要为 SuperClass 创建外键
标签: java hibernate jpa criteria