0

I try to implement single table inheritance with hibernate 5.2 . Base Class

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type", discriminatorType= DiscriminatorType.STRING)
@DiscriminatorValue("HAKSAHIBI")
@DiscriminatorOptions(force=true)
public class PropertyOwner implements  implements Serializable{
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    long id;
    @ManyToOne 
    Property property;
   @ManyToOne
 Person person; 

}

Author class extends PropertyOwner :

@Entity 
@DiscriminatorValue("AUTHOR")
class Author extends PropertyOwner {
}

Composer class extends PropertyOwner :

@Entity 
@DiscriminatorValue("COMPOSER")
class Composer extends PropertyOwner {
}

Person Class :

public class Person {
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    long id;
String title; 
}

Property class

public class Property{
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    long id;
String title; 

@OneToMany
Set<Composer> composers = new HashSet<Composer>();

@OneToMany
Set<Author> authors = new HashSet<Author>(); 
}

I am expecting table structure as following :

CREATE TABLE `Property` (
  `id` bigint(20) NOT NULL,
  `title` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `Person` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `PropertyOwner` (
  `type` varchar(31) NOT NULL,
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `property_id` bigint(20) DEFAULT NULL,
  `person_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FK77apjkkl14xwe45rs1ocgtt4u` (`property_id`),
  KEY `FKqagfofgupovfly26enivfhm3j` (`person_id`),
  CONSTRAINT `FK77apjkkl14xwe45rs1ocgtt4u` FOREIGN KEY (`property_id`) REFERENCES `property` (`id`),
  CONSTRAINT `FKqagfofgupovfly26enivfhm3j` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

But unfortunately it creates another table for Author and Composer classes with following statement

CREATE TABLE `property_propertyOwner` (
  `Property_id` bigint(20) NOT NULL,
  `author_id` bigint(20) NOT NULL,
  `composer_id` bigint(20) NOT NULL,
  UNIQUE KEY `UK_rv9fxc06rcydqp6dqpqbmrkie` (`author_id`),
  UNIQUE KEY `UK_fm4v55i021l5smuees0vs3qmy` (`composer_id`),
  KEY `FKt3yqcltkd0et8bj08ge0sgrqb` (`Property_id`),
  CONSTRAINT `FK1pj2606cjxrb70ps89v7609hg` FOREIGN KEY (`author_id`) REFERENCES `PropertyOwner` (`id`),
  CONSTRAINT `FKfdh3r95jffvd07u3xn21824r7` FOREIGN KEY (`composer_id`) REFERENCES `PropertyOwner` (`id`),
  CONSTRAINT `FKt3yqcltkd0et8bj08ge0sgrqb` FOREIGN KEY (`Property_id`) REFERENCES `Property` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

What I am doing wrong ? I am expecting property_PropertyOwner table should not be created and Author , Composer classes information should hold in propertyOwner table.

Note : I tried Enumarated annotation but this time in Property class I can not define Setauthor field , I must define Set and add enum information to that object. Thanks in advance .

Osman Corluk
  • 325
  • 1
  • 3
  • 12
  • Seems like you are missing the `mappedBy` in your mapping. Use `@OneToMany(mappedBy = "property")` and `@OneToMany(mappedBy = "person")` – Christian Beikov Mar 12 '17 at 17:28

1 Answers1

1

There is no point in having multiple associations of subclasses (Composers and authors) in your property entity.As you are having single table inheritance i.e your property owner table will have a foreign key of property_id. So instead that you can have single association .

@OneToMany
Set<PropertyOwner> composers = new HashSet<PropertyOwner>();

And you can split this set into authors and composer in memory using DiscriminatorColumn type.

shubham
  • 472
  • 3
  • 9
  • I want to use Author and Composer object in Property and in database due to performance issues single table would hold data. If I change PropertyOwner I can not use Author as an object. – Osman Corluk Mar 12 '17 at 11:57
  • Since you are using single table inheritance you will get author or composer object in property entity. Hibernate will cast this to proper subclass object depending on the discrimator value. – shubham Mar 12 '17 at 12:18