0

I have an entity which extends another entity:

@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;
...

When I try to query for a parkingPoi I get nor results.

        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();

(Both, the active and the outcommented queries have no results.)

In the database I have a table pois for the parent class and a "subtable" for parkingPois which holds a foreign key (pois.poiId).

What can be the reason??

du-it
  • 2,561
  • 8
  • 42
  • 80
  • Have you tried executing generated query in database to see whether any query does have any results? – Jacob Jun 28 '14 at 12:43

2 Answers2

1

I had to add a parkingPoiId property to your ParkingPoiDaoentity so that the ParkingPoiDao.findById named query was valid:

@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;
    }
}

So with that added, the following test passes using both of your queries:

@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);
}

Could you confirm what the difference is with your entities and perhaps add details of how you are persisting your ParkingPoiDao entities?

Donovan Muller
  • 3,822
  • 3
  • 30
  • 54
  • I have already a parkingPoiId property in ParkingPoiDao. I think the problem is based upon the fact that tha poiType column (which is the discriminator column) in PoiDao is an enum!?? – du-it Jun 30 '14 at 07:31
  • I'm not sure I understand you. The `discriminatorType` accepts a `javax.persistence.DiscriminatorType` (which is an enum) but that's by design. If it is still not working, perhaps you can put up a sample project on GitHub or something to take a look at? – Donovan Muller Jun 30 '14 at 08:47
0

I am implementing joined, multiple table inheritance. Joined inheritance is the most logical inheritance solution because it mirrors the object model in the data model. In joined inheritance a table is defined for each class in the inheritance hierarchy to store only the local attributes of that class. Each table in the hierarchy must also store the object's id (primary key), which is only defined in the root class. All classes in the hierarchy must share the same id attribute. A discriminator column is used to determine which class the particular row belongs to, each class in the hierarchy defines its own unique discriminator value.

The problem was that I had to add @ObjectTypeConverter annotation on class level as well as @Convert annotation on field level:

@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;
    ...
}

Of course, the respective values must be in the database if records are already in the table(s).

du-it
  • 2,561
  • 8
  • 42
  • 80