4

I have an abstract parent class with two child classes, where I want the child classes to have their own tables. I also have another class that has a relationship to the parent class:

// Class that has the mapping to the abstract class
@Entity
@Table(name="telephone_numbers")
public class TelephoneNumber implements Serializable {

    @Id
    @Column(name="number")
    private String number;

    @Column(name="originating_carrier")
    private String originatingCarrier;

    @OneToOne(mappedBy = "number")
    private TelephoneNumberAssignment assignment;

... getters and setters ...

}

// Classes involved in inheritance
public abstract class TelephoneNumberAssignment implements Serializable {

    @Id
    @OneToOne
    @JoinColumn(name="number")
    private TelephoneNumber number;

        ... getters and setters ...
}

@Entity
@Table(name="telephone_numbers_fixed_line")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class FixedLineNumberAssignment extends TelephoneNumberAssignment {

    @Column(name="recorded")
    private Boolean recorded;

    public FixedLineNumberAssignment() {
    }

        ... getters and setters ...

}

@Entity
@Table(name="telephone_numbers_mobile")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class MobileNumberAssignment extends TelephoneNumberAssignment {

    @ManyToOne
    @JoinColumn(name = "customer_id")
    private Customer customer;

    public MobileNumberAssignment() {
    }

        ... getters and setters ...

}

According to the answer to this question, in order for my JPA annotations in the superclass to carry over to the child class I need to use @MappedSuperclass. However, due to the requirement of the mapping to the superclass, a following exception occurs:

Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.vtsl.domain.numbering.TelephoneNumber.assignment, referenced property unknown: com.vtsl.domain.numbering.TelephoneNumberAssignment.number

According to the answer to this question I could use TABLE_PER_CLASS to solve this issue. However, if I do that my superclass JPA annotations don't seem to carry over; if I perform JPQL query

return entityManager.createQuery("SELECT mob FROM MobileNumberAssignment as mob INNER JOIN FETCH mob.number", MobileNumberAssignment.class).getResultList();

the results returned do not have their number field populated (upon further inspection I found that hibernate does not detect the number property when trying to resolve the properties on the result object). However, when I perform the following:

//Result set has 1 object
entityManager
    .createQuery("SELECT mob FROM MobileNumberAssignment as mob INNER JOIN FETCH mob.number WHERE mob.number.number = :number", MobileNumberAssignment.class)
    .setParameter("number", "number that exists")
    .getResultList()

//Result set has 0 object
entityManager
    .createQuery("SELECT mob FROM MobileNumberAssignment as mob INNER JOIN FETCH mob.number WHERE mob.number.number = :number", MobileNumberAssignment.class)
    .setParameter("number", "number that does not exist")
    .getResultList()

the results seem to indicate that the parameter got successfully resolved after all.

Why is it that the number property does not get populated?

Community
  • 1
  • 1
Domas Poliakas
  • 836
  • 6
  • 19

1 Answers1

0

It appears I have drawn all the wrong conclusions from the symptoms. The issue was not at all with the inheritance specification, but rather with the specification of the mapped primary key. According to every resource I found

@Id
@OneToOne
@JoinColumn(name="number")
private TelephoneNumber number;

should work just fine, however it seems that in the version of hibernate I am using (4.10) it does not. Changing the mapping to use @MapsId resolved the issues I was observing, making the new (and now working) TelephoneNumberAssignment to look like:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class TelephoneNumberAssignment implements Serializable {

    @Id String numberString;

    @MapsId
    @OneToOne
    @JoinColumn(name="number")
    private TelephoneNumber number;

    ... getters and setters ...
}
Domas Poliakas
  • 836
  • 6
  • 19