Showing posts with label InheritanceType.TABLE_PER_CLASS. Show all posts
Showing posts with label InheritanceType.TABLE_PER_CLASS. Show all posts

Thursday, October 26, 2017

Hibernate Inheritance Mapping

Inheritance

MappedSuperclass

Totally separated tables in database. Two tables will be created for DebitAccount and CreditAccount. No fetching against subclass is available.

@MappedSuperclass
public static class Account {
 
    @Id
    private Long id;
 
}
 
@Entity(name = "DebitAccount")
public static class DebitAccount extends Account {
 
    private BigDecimal overdraftFee;
}
 
@Entity(name = "CreditAccount")
public static class CreditAccount extends Account {
 
    private BigDecimal creditLimit;
}

Single Table (default choice for JPA)

Each subclass in a hierarchy must define a unique discriminator value, which is used to differentiate between rows belonging to separate subclass types. If this is not specified, the DTYPE column is used as a discriminator, storing the associated subclass name.

@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public static class Account {
 
    @Id
    private Long id;
}
 
@Entity(name = "DebitAccount")
public static class DebitAccount extends Account {
 
    private BigDecimal overdraftFee;
}
 
@Entity(name = "CreditAccount")
public static class CreditAccount extends Account {
 
    private BigDecimal creditLimit;
}

@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula(
    "case when debitKey is not null " +
    "then 'Debit' " +
    "else ( " +
    "   case when creditKey is not null " +
    "   then 'Credit' " +
    "   else 'Unknown' " +
    "   end ) " +
    "end "
)
//@DiscriminatorColumn(
//    name="type",
//    discriminatorType=DiscriminatorType.STRING)
// only STRING, CHAR, INTEGER are valid
public static class Account {
 
    @Id
    private Long id;
}
 
@Entity(name = "DebitAccount")
@DiscriminatorValue(value = "Debit")
public static class DebitAccount extends Account {
 
    private String debitKey;
}
 
@Entity(name = "CreditAccount")
@DiscriminatorValue(value = "Credit")
public static class CreditAccount extends Account {
 
    private String creditKey;
}


@Entity(name = "Account")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorValue( "null" )
public static class Account {
 
    @Id
    private Long id;
}
 
@Entity(name = "DebitAccount")
@DiscriminatorValue( "Debit" )
public static class DebitAccount extends Account {
 
    private BigDecimal overdraftFee;
}
 
@Entity(name = "CreditAccount")
@DiscriminatorValue( "Credit" )
public static class CreditAccount extends Account {
 
    private BigDecimal creditLimit;
 
}
 
@Entity(name = "OtherAccount")
@DiscriminatorValue( "not null" )
public static class OtherAccount extends Account {
 
    private boolean active;
}

Joined Table

Tables for subclasses will have a foreign key column that points back to superclass.

@Entity(name = "Account")

@Inheritance(strategy = InheritanceType.JOINED)
public static class Account {
 
    @Id
    private Long id;
}
 
@Entity(name = "DebitAccount")
public static class DebitAccount extends Account {
 
    private BigDecimal overdraftFee;
}
 
@Entity(name = "CreditAccount")
public static class CreditAccount extends Account {
 
    private BigDecimal creditLimit;
}


@Entity(name = "Account")

@Inheritance(strategy = InheritanceType.JOINED)
public static class Account {
 
    @Id
    private Long id;
}
 
@Entity(name = "DebitAccount")
@PrimaryKeyJoinColumn(name = "account_id")
public static class DebitAccount extends Account {
 
    private BigDecimal overdraftFee;
}
 
@Entity(name = "CreditAccount")
@PrimaryKeyJoinColumn(name = "account_id")
public static class CreditAccount extends Account {
 
    private BigDecimal creditLimit;
}

Table per (concrete) class

@Entity(name = "Account")

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public static class Account {
 
    @Id
    private Long id;
}
 
@Entity(name = "DebitAccount")
public static class DebitAccount extends Account {
 
    private BigDecimal overdraftFee;
}
 
@Entity(name = "CreditAccount")
public static class CreditAccount extends Account {
 
    private BigDecimal creditLimit;
}

Immutable

Hibernate skips any updates if the @Immutable has been used.
@Entity(name = "Batch")
public static class Batch {

    @Id
    private Long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL)
    @Immutable
    private List<Event> events = new ArrayList<>( );

    //Getters and setters are omitted for brevity

}

@Entity(name = "Event")
@Immutable
public static class Event {

    @Id
    private Long id;

    private Date createdOn;

    private String message;

    //Getters and setters are omitted for brevity

}