Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thergbway/58d8f2a6ebad86c7b3eead4dcfadd2d6 to your computer and use it in GitHub Desktop.
Save thergbway/58d8f2a6ebad86c7b3eead4dcfadd2d6 to your computer and use it in GitHub Desktop.
HIBERNATE&JPA. JPA ENTITY INHERITANCE
1. Типы классов в иерархии наследования:
* Сущность. Проблем нет, используется во всех примерах данного модуля
* Абстрактная сущность. Рассматривается так же, как и обычная сущность, только создать её объект нельзя.
* Суперкласс, который не является сущностью, те без @Entity. При расширении его классом, помеченным @Entity,
JPA будет видеть только свойства класса-потомка, а не базового класса, тк он не помечен @Entity
* Отображенный суперкласс. Не является сущностью, помечается @MappedSuperclass. Служит основой для
потомков-сущностей. К нему нельзя делать запросы и тп, тк это не сущность. Его поля будут отображены в таблице
расширяющего его класса-сущности.
package inheritance.joined_table;
import lombok.*;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
/*
Несколько таблиц, каждый подкласс в своей таблице, со своими (не унаследованными) полями.
В корневой таблице будет лежать id и дискриминатор сущности. Их можно настроить через
@DiscriminatorColumn и @DiscriminatorValue, либо оставить по умолчанию
*/
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(
name = "discriminator"//default name - DTYPE
)
@DiscriminatorValue("THuman")//optional
public class Human {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String name;
}
package inheritance.joined_table;
import lombok.*;
import javax.persistence.*;
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Entity
@DiscriminatorValue("TStudent")
public class Student extends Human {
private String university;
public Student() {}
public Student(Long id, String name, String university) {
super(id, name);
this.university = university;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n"/>
</layout>
</appender>
<!--Turn on your favourite loggers-->
<logger name="org.hibernate">
<level value="WARN"/><!--or DEBUG for more verbose logging-->
</logger>
<logger name="org.hibernate.SQL">
<level value="INFO"/>
</logger>
<root>
<level value="WARN"/>
<appender-ref ref="stdout"/>
</root>
</log4j:configuration>
package inheritance;
import inheritance.joined_table.*;
import inheritance.single_table.*;
import inheritance.table_per_class.*;
import org.apache.log4j.Logger;
import javax.persistence.*;
import static java.util.Objects.nonNull;
public class Main {
private static final Logger log = Logger.getLogger(Main.class);
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate-jpa-persistence-unit");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = null;
try {
tx = em.getTransaction();
tx.begin();
Item item = new Item(null, "item_title_example");
Book book = new Book(null, "book_title_example", "1a2b3c");
em.persist(item);
em.persist(book);
Human human = new Human(null, "Jerry Smith");
Student student = new Student(null, "Albert Einstein", "Berlin Technical University");
em.persist(human);
em.persist(student);
Car car = new Car(null, "Usual car", 6L);
MegaCar megaCar = new MegaCar(null, "MegaCar2000", 100L, "Swim");
em.persist(car);
em.persist(megaCar);
tx.commit();
tx = em.getTransaction();
tx.begin();
item = em.find(Item.class, item.getId());
book = em.find(Book.class, book.getId());
System.out.println(item);
System.out.println(book);
human = em.find(Human.class, human.getId());
student = em.find(Student.class, student.getId());
System.out.println(human);
System.out.println(student);
car = em.find(Car.class, car.getId());
megaCar = em.find(MegaCar.class, megaCar.getId());
System.out.println(car);
System.out.println(megaCar);
tx.commit();
} catch (Exception e) {
log.error("Got exception!", e);
if (nonNull(tx) && tx.isActive())
tx.rollback();
} finally {
if (nonNull(em))
em.close();
if (nonNull(emf))
emf.close();
}
}
}
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="hibernate-jpa-persistence-unit">
<description>Persistence unit for the Hibernate JPA</description>
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.thergbway</groupId>
<artifactId>jpa_inheritance</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.192</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.20.0-GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.2.3.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>initialize</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package inheritance.single_table;
import lombok.*;
import javax.persistence.*;
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Entity
@DiscriminatorValue("B")
public class Book extends Item{
private String isbn;
public Book() {}
public Book(Long id, String title, String isbn) {
super(id, title);
this.isbn = isbn;
}
}
package inheritance.single_table;
import lombok.*;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
/*
Все потомки будут сохранены в эту таблицу, все свойства всех подклассов будут занесены в одну таблицу.
Будет много пропусков данных. Недостаток - все свойства подклассов не могут быть not null, те только nullable
*/
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)//default type - SINGLE_TABLE
@DiscriminatorColumn(
name = "discriminator",//default name - DTYPE
discriminatorType = DiscriminatorType.CHAR//default type - STRING
)
@DiscriminatorValue("I")//optional
public class Item {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String title;
}
package inheritance.table_per_class;
import lombok.*;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
/*
Для каждого подкласса будет своя таблица со всеми его свойствами, в тч унаследованными.
Используй @AttributeOverride или @AttributeOverrides для переопределения унаследованных свойств(задания нового
имени для таких столбцов в потомках)
*/
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String name;
private Long gears;
}
package inheritance.table_per_class;
import lombok.*;
import javax.persistence.*;
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Entity
@AttributeOverrides({
@AttributeOverride(name = "gears", column = @Column(name = "gears_number"))//не работает, но должно
})
public class MegaCar extends Car{
private String ability;
public MegaCar() {}
public MegaCar(Long id, String name, Long gears, String ability) {
super(id, name, gears);
this.ability = ability;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment