Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thergbway/a5ebd11af6bd4dfa4600da32f50d37da to your computer and use it in GitHub Desktop.
Save thergbway/a5ebd11af6bd4dfa4600da32f50d37da to your computer and use it in GitHub Desktop.
HIBERNATE&JPA. JPA HIBERNATE MULTIPLICITY ENTITY RELATIONSHIP
1. Связи бывают однонаправленными и двунаправленными: unidirectional и bidirectional. На UML стрелка с направлением, либо
одна соединительная линия. В реляционных БД связи осуществляются с использованием внешнего ключа(1-1) или
таблицы соединения(1-N, N-N)
2. Множественность связи или кардинальность. На UML обозначается, как 0..*, 1, 1..*, 1..2, 3..6 и так далее. Связь
с более чем одним объектом является типом Collection, List, Set, Map.
3. Владелец связи. При однонаправленной связи владелец - инициатор связи, при двунаправленной связи надо явно указывать
4. Каждая из связей однонаправленная или двунаправленная может быть @OneToOne, @OneToMany, @ManyToOne, @ManyToMany.
Все возможные виды связей(многие очень похожи друг на друга, поэтому достаточно запомнить лишь некоторые):
#Тип связи #Направление
* OneToOne Unidirectional
* OneToOne Bidirectional
* OneToMany Unidirectional
* OneToMany/ManyToOne Bidirectional
* ManyToOne Unidirectional
* ManyToMany Unidirectional
* ManyToMany Bidirectional
5. При однонаправленной связи настраиваем параметры внешнего ключа/таблицы во владеющей сущности,
если связь двунаправленная, то владеющая сторона определяет параметры, а противоположная указывает в поле mappedBy
имя соответствующего параметра владеющей связью сущности. mappedBy указывается для @OneToOne, @OneToMany, @ManyToMany,
но никогда для @ManyToOne
6. Разумно правильно определять отложена загрузка сущности или нет (fetch = LAZY or EAGER).
Для аннотаций @OneToOne, @ManyToOne fetch=EAGER, а для @OneToMany, @ManyToMany fetch=LAZY
7. Можно для сущности задавать упорядочение элементов-коллекций:
* @OrderBy(attribute_name_1 DESC, attribute_name_2 ASC). Упорядочение при выборке согласно указанным аттрибутам сущности
* @OrderColumn(name = "column_index_name"). Коллекция будет упорядочена в соответствии с индексом элементов,
записанных с отдельном столбце. Есть потеря производительности, тк данный столбец надо держать актуальным
package relationship.bidirectional_many_to_many;
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Artist {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@ManyToMany
@JoinTable(
name = "artist_to_cd",
joinColumns = @JoinColumn(name = "artist_id"),
inverseJoinColumns = @JoinColumn(name = "cd_id")
)
private List<CD> involvedOnCds;
@Override
public String toString() {
return "Artist{" + "id=" + id + ", involvedOnCds={...}}";
}
}
package relationship.bidirectional_many_to_many;
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class CD {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String title;
@ManyToMany(mappedBy = "involvedOnCds")
private List<Artist> involvedArtists;
}
<?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 relationship;
import org.apache.log4j.Logger;
import relationship.bidirectional_many_to_many.*;
import relationship.unidirectional_one_to_many.*;
import relationship.unidirectional_one_to_one.*;
import javax.persistence.*;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
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();
Address address = new Address(null, "6th Avenue", "New York City");
em.persist(address);
Customer customer = new Customer(null, "Jack", "jack@hotmail.com", address);
em.persist(customer);
OrderLine o1 = new OrderLine(null, 200L);
OrderLine o2 = new OrderLine(null, 300L);
em.persist(o1);
em.persist(o2);
Order order = new Order(null, asList(o1, o2));
em.persist(order);
Artist artist1 = new Artist();
Artist artist2 = new Artist();
Artist artist3 = new Artist();
em.persist(artist1);
em.persist(artist2);
em.persist(artist3);
CD cd1 = new CD(null, "CD1", asList(artist1, artist2));
CD cd2 = new CD(null, "CD1", asList(artist2, artist3));
em.persist(cd1);
em.persist(cd2);
artist1.setInvolvedOnCds(singletonList(cd1));
artist2.setInvolvedOnCds(asList(cd1, cd2));
artist3.setInvolvedOnCds(singletonList(cd2));
tx.commit();
tx = em.getTransaction();
tx.begin();
customer = em.find(Customer.class, customer.getId());
System.out.println(customer);
order = em.find(Order.class, order.getId());
System.out.println(order);
cd1 = em.find(CD.class, cd1.getId());
cd2 = em.find(CD.class, cd2.getId());
System.out.println(cd1);
System.out.println(cd2);
tx.commit();
} catch (Exception e) {
log.error("Got error!", 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>entity_relationships</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 relationship.unidirectional_one_to_many;
import lombok.*;
import javax.persistence.*;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "orders")
public class Order {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
@OneToMany
//@JoinColumn(name = "order_id") for mapping in the Address table
//for mapping in the external table
@JoinTable(
name = "order_to_order_line",
joinColumns = @JoinColumn(name = "order_id"),
inverseJoinColumns = @JoinColumn(name = "order_line_id")
)
private List<OrderLine> orderLine;
}
package relationship.unidirectional_one_to_many;
import lombok.*;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class OrderLine {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private Long totalCost;
}
package relationship.unidirectional_one_to_one;
import lombok.*;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Address {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String street;
private String city;
}
package relationship.unidirectional_one_to_one;
import lombok.*;
import javax.persistence.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Customer {
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String name;
private String email;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "address_id", nullable = false)
private Address address;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment