JPA:TypedQuery没有获得继承类型的结果

时间:2014-06-28 12:25:51

标签: inheritance jpa named-query

我有一个扩展另一个实体的实体:

@Entity
@DiscriminatorValue("PARKING")
@Table(name="parkingPois")
@NamedQueries({
    @NamedQuery(name="ParkingPoiDao.findAll", query="SELECT p FROM ParkingPoiDao p"), 
    @NamedQuery(name="ParkingPoiDao.findById", query="SELECT p FROM ParkingPoiDao p WHERE p.parkingPoiId = :parkingPoiId")
})
public class ParkingPoiDao extends PoiDao implements Serializable {
    //@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;
    @Column(name="parkingPoiId")
    private String parkingPoiId;
    @Column(name="poiId")
    ...
}

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="poiType", discriminatorType=DiscriminatorType.STRING)
@Table(name="pois")
public abstract class PoiDao implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="poiId")
    private int poiId;
...

当我尝试查询parkingPoi时,我得到的也没有结果。

        TypedQuery<ParkingPoiDao> query =
                em.createNamedQuery("ParkingPoiDao.findAll", ParkingPoiDao.class);
//      TypedQuery<ParkingPoiDao> query =
//              em.createNamedQuery("ParkingPoiDao.findById", ParkingPoiDao.class)
//              .setParameter("parkingPoiId", facilityId);
//              .setParameter("poiType", "ParkingPOI");
//      ParkingPoiDao pPoiDao = query.getSingleResult();
        List<ParkingPoiDao> pPoiDaos = query.getResultList();

(两者,活动和已过时的查询都没有结果。)

在数据库中,我有一个用于父类的表 pois 和用于 parkingPois 的“子表”,它包含一个外键(pois.poiId)。

可能是什么原因?

2 个答案:

答案 0 :(得分:1)

我必须向parkingPoiId实体添加ParkingPoiDao属性,以便ParkingPoiDao.findById命名查询有效:

@Entity
@Table(name="parkingPois")
@NamedQueries({
        @NamedQuery(name="ParkingPoiDao.findAll", query="SELECT p FROM ParkingPoiDao p"),
        @NamedQuery(name="ParkingPoiDao.findById", query="SELECT p FROM ParkingPoiDao p WHERE p.parkingPoiId = :parkingPoiId")
})
public class ParkingPoiDao extends PoiDao {

    private String parkingPoiId;

    public String getParkingPoiId() {
        return parkingPoiId;
    }

    public void setParkingPoiId(final String parkingPoiId) {
        this.parkingPoiId = parkingPoiId;
    }
}

因此添加了以下测试后,使用两个查询:

@Test
@Transactional
public void return_parking_pois() {
    ParkingPoiDao parkingPoi = new ParkingPoiDao();
    parkingPoi.setParkingPoiId("123");
    em.persist(parkingPoi);

    TypedQuery<ParkingPoiDao> query = em
            .createNamedQuery("ParkingPoiDao.findById", ParkingPoiDao.class)
            .setParameter("parkingPoiId", "123");
    List<ParkingPoiDao> pPoiDaos = query.getResultList();

    assertThat(pPoiDaos).hasSize(1);

    query = em.createNamedQuery("ParkingPoiDao.findAll", ParkingPoiDao.class);
    pPoiDaos = query.getResultList();

    assertThat(pPoiDaos).hasSize(1);
}

您能否确认与您的实体有何不同之处,或者可能会添加有关如何保留ParkingPoiDao个实体的详细信息?

答案 1 :(得分:0)

我正在实现连接,多表继承。 连接继承是最合理的继承解决方案,因为它反映了数据模型中的对象模型。在连接继承中,为继承层次结构中的每个类定义一个表,以仅存储该类的本地属性。层次结构中的每个表还必须存储对象的id(主键),该id仅在根类中定义。层次结构中的所有类必须共享相同的id属性。鉴别器列用于确定特定行所属的类,层次结构中的每个类定义其自己的唯一鉴别器值。

问题是我必须在类级别添加 @ObjectTypeConverter 注释以及在字段级别添加 @Convert 注释:

@ObjectTypeConverters({
    @ObjectTypeConverter (
            name="poiTypeConverter",
            dataType=java.lang.String.class,
            objectType=ServiceTypeEnum.class,
            conversionValues={
                @ConversionValue(dataValue="CHARGING", objectValue="CHARGING"),
                @ConversionValue(dataValue="PARKING", objectValue="PARKING")
            }
    )
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="poiType", discriminatorType=DiscriminatorType.STRING)
@Table(name="pois")
public abstract class PoiDao implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="poiId")
    private int poiId;
    @Convert("poiTypeConverter")
    private ServiceTypeEnum poiType;
...

@Entity
@DiscriminatorValue("PARKING")
@Table(name="parkingPois")
@NamedQueries({
    @NamedQuery(name="ParkingPoiDao.findAll", query="SELECT p FROM ParkingPoiDao p"), 
    @NamedQuery(name="ParkingPoiDao.findById", query="SELECT p FROM ParkingPoiDao p WHERE p.parkingPoiId = :parkingPoiId")
})
public class ParkingPoiDao extends PoiDao implements Serializable {
    //@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;
    @Column(name="parkingPoiId")
    private String parkingPoiId;
    @Column(name="poiId")
    @Convert("parkingPoiStatusConverter")
    @Column(name="status")
    private ParkingPoiStatusEnum status;
    ...
}

当然,如果记录已经在表格中,则各个值必须在数据库中。