- By default, a unidirectional one-to-many association uses an intermediate join table to store the relationship. This default mapping is also referred as 'one-to-many join table mapping strategy'.
- In 'one-to-many foreign key mapping strategy', instead of using a join table, we use a foreign key column in the 'target' table. This foreign key column stores the references of primary keys from the 'source' table.
- To use this strategy we have to use @JoinColumn annotation along with @OneToMany in the source entity.
Example
@Entity
public class EntityA {
@Id
@GeneratedValue
private int myIdA;
private String strA;
@OneToMany
@JoinColumn(name = "MY_FK_COL")
private List<EntityB> entityBList;
.............
}
@Entity
public class EntityB {
@Id
@GeneratedValue
private int myIdB;
private String strB;
.............
}
public class ExampleMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test1");
try {
EntityManager em = emf.createEntityManager();
nativeQuery(em, "SHOW TABLES");
nativeQuery(em, "SHOW COLUMNS from EntityA");
nativeQuery(em, "SHOW COLUMNS from EntityB");
emf.close();
} finally {
emf.close();
}
}
public static void nativeQuery(EntityManager em, String s) {
System.out.printf("--------%n'%s'%n", s);
Query query = em.createNativeQuery(s);
List list = query.getResultList();
for (Object o : list) {
if (o instanceof Object[]) {
System.out.println(Arrays.toString((Object[]) o));
} else {
System.out.println(o);
}
}
}
} Output-------- 'SHOW TABLES' [ENTITYA, PUBLIC] [ENTITYB, PUBLIC] -------- 'SHOW COLUMNS from EntityA' [MYIDA, INTEGER(10), NO, PRI, NULL] [STRA, VARCHAR(255), YES, , NULL] -------- 'SHOW COLUMNS from EntityB' [MYIDB, INTEGER(10), NO, PRI, NULL] [STRB, VARCHAR(255), YES, , NULL] [MY_FK_COL, INTEGER(10), YES, , NULL]
H2 database SHOW statements
The above output shows that no 'join table' is generated, instead a foreign-key column, MY_FK_COL has been used to persist the relationship. If we don't specify 'name' element of @JoinColumn, the default ENTITYBLIST_MYIDA will be used.
Following diagram gives a quick overview of the relationship
Let's persist some data.
public class ExampleMain2 {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test1");
try {
persistEntity(emf);
nativeQueries(emf);
loadEntityA(emf);
loadEntityB(emf);
} finally {
emf.close();
}
}
private static void nativeQueries(EntityManagerFactory emf) {
System.out.println("-- native queries --");
EntityManager em = emf.createEntityManager();
ExampleMain.nativeQuery(em, "Select * from EntityA");
ExampleMain.nativeQuery(em, "Select * from EntityB");
}
private static void persistEntity(EntityManagerFactory emf) {
EntityManager em = emf.createEntityManager();
EntityB entityB = new EntityB();
entityB.setStrB("testStringB");
EntityB entityB2 = new EntityB();
entityB2.setStrB("testStringB2");
EntityA entityA = new EntityA();
entityA.setStrA("testStringA");
entityA.setEntityBList(Arrays.asList(entityB, entityB2));
System.out.println("-- Persisting entities --");
System.out.println(entityA);
em.getTransaction().begin();
em.persist(entityA);
em.persist(entityB);
em.persist(entityB2);
em.getTransaction().commit();
em.close();
}
private static void loadEntityA(EntityManagerFactory emf) {
System.out.println("-- Loading EntityA --");
EntityManager em = emf.createEntityManager();
List<EntityA> entityAList = em.createQuery("Select t from EntityA t").getResultList();
entityAList.forEach(System.out::println);
em.close();
}
private static void loadEntityB(EntityManagerFactory emf) {
System.out.println("-- Loading EntityB --");
EntityManager em = emf.createEntityManager();
List<EntityB> entityBList = em.createQuery("Select t from EntityB t").getResultList();
entityBList.forEach(System.out::println);
em.close();
}
} Output-- Persisting entities -- EntityA{myIdA=0, entityBList=[EntityB{myIdB=0, strB='testStringB'}, EntityB{myIdB=0, strB='testStringB2'}], strA='testStringA'} -- native queries -- -------- 'Select * from EntityA' [1, testStringA] -------- 'Select * from EntityB' [2, testStringB, 1] [3, testStringB2, 1] -- Loading EntityA -- EntityA{myIdA=1, entityBList=[EntityB{myIdB=2, strB='testStringB'}, EntityB{myIdB=3, strB='testStringB2'}], strA='testStringA'} -- Loading EntityB -- EntityB{myIdB=2, strB='testStringB'} EntityB{myIdB=3, strB='testStringB2'}
Example ProjectDependencies and Technologies Used: - h2 1.4.193: H2 Database Engine.
- hibernate-core 5.2.8.Final: The core O/RM functionality as provided by Hibernate.
Implements javax.persistence:javax.persistence-api version 2.1 - JDK 1.8
- Maven 3.3.9
|
|