1

I have the following code

interface Loanable {}

abstract class Material {}

@Entity
class Journal extends Material {}

@Entity
class Book extends Material implements Loanable {}

@Entity
class DigitalMedia extends Material implements Loanable {}

@Entity
@Table(name = "Loan")
@Access(value = AccessType.FIELD)
public class Loan {
    @Id
    @Column(name="Loan_ID",updatable = false, nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @OneToOne (cascade=CascadeType.ALL)
    @JoinColumn(name="studentId")
    /* Person who makes the loan */
    private User user;

    //@Column(name="loanable")
    @OneToOne (cascade=CascadeType.ALL)
    @JoinColumn(name="materialId")
    /* Loanble which is loaned */
    private Loanable loanable;
}

As shown in the code, I'm trying to map Loan to a Loanable. One User can have one loan at a time. How can I map the loanable type object to the database? I searched of the method of making an abstract class and extend it in Book and DigitalMedia, but I can't extend two classes since they already extend Material. @Convert also doesn't seem to work on interface type of objects. I'm using JPA with Hibernate persistence.

manish
  • 19,695
  • 5
  • 67
  • 91
Harvey
  • 572
  • 1
  • 7
  • 23
  • When asking a question, please post code instead of describing your code as it is easier to understand the question from the actual code. Also make sure to post only as much code as is relevant to the problem, avoiding posting any parts that have no bearing on the problem. – manish May 27 '18 at 12:17
  • Only some JPA providers support interfaces. Sounds like your JPA provider doesn't –  May 27 '18 at 17:46

1 Answers1

1

JPA entities need to be classes, so trying to map an interface will not work. The mapped classes need not necessarily be concrete, so abstract classes work with associations.

The following should work:

@MappedSuperclass
abstract class Material {}

@MappedSuperclass
abstract class LoanableMaterial extends Material implements Loanable {}

@Entity
class Journal extends Material {}

@Entity
class Book extends LoanableMaterial {}

@Entity
class DigitalMedia extends LoanableMaterial {}

@Entity
class Loan {
  @ManyToOne(targetEntity = LoanableMaterial.class)
  LoanableMaterial loaned;
}

The association between Loan and Loanable is many-to-many. This is because although one material can be loaned to only one student at a time, it can be loaned to multiple students at different times. Similarly, although one student can loan only one material at a time, that same student can loan many materials at different times. The association from Loan to User should therefore be ManyToOne as well.

manish
  • 19,695
  • 5
  • 67
  • 91