- Similar to one-to-one association, many-to-one association supports a source entity having a reference of another entity (the target entity), but unlike one-to-one association, many-to-one association also supports multiple instances of the source entity sharing a single target entity instance.
- To establish this relationship, @ManyToOne annotation is used in the source entity class. It is placed on the filed/property of the target entity.
- On the target side, we don't need to use any relational annotation unless it's a bidirectional association.
- The table corresponding to the source entity, is the child-table which has a foreign key column, whereas the table corresponding to the target entity, is the parent table which has the corresponding primary key column.
- The foreign key column in the child-table must not be unique so it can be populated with a single parent's primary key multiple times, thus forming a many to one relationship.
@ManyToOne example
@Entity
public class EntityA {
@Id
@GeneratedValue
private int myIdA;
@ManyToOne
private EntityB refEntityB;
.............
}
@Entity
public class EntityB {
@Id
@GeneratedValue
private int myIdB;
private String str;
.............
}
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) {
System.out.println(Arrays.toString((Object[]) o));
}
}
} Output--------------------------- 'SHOW TABLES' [ENTITYA, PUBLIC] [ENTITYB, PUBLIC] --------------------------- 'SHOW COLUMNS from EntityA' [MYIDA, INTEGER(10), NO, PRI, NULL] [REFENTITYB_MYIDB, INTEGER(10), YES, , NULL] --------------------------- 'SHOW COLUMNS from EntityB' [MYIDB, INTEGER(10), NO, PRI, NULL] [STR, VARCHAR(255), YES, , NULL]
H2 database SHOW statements
Here's a quick review of the relationship:
Just like @OneToOne, we can use @JoinColumn along with @ManyToOne to specify a different foreign key column name.
Persisting data
We are going to populate multiple instances of source EntityA with a single instance of target EntityB.
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) {
EntityManager em = emf.createEntityManager();
ExampleMain.nativeQuery(em, "Select * from EntityA");
ExampleMain.nativeQuery(em, "Select * from EntityB");
}
private static void persistEntity(EntityManagerFactory emf) {
System.out.println("-- Persisting entities --");
EntityManager em = emf.createEntityManager();
EntityB entityB = new EntityB();
entityB.setStr("testStringB");
EntityA entityA = new EntityA();
entityA.setRefEntityB(entityB);
EntityA entityA2 = new EntityA();
entityA2.setRefEntityB(entityB);
em.getTransaction().begin();
em.persist(entityA);
em.persist(entityA2);
em.persist(entityB);
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 -- --------------------------- 'Select * from EntityA' [1, 3] [2, 3] --------------------------- 'Select * from EntityB' [3, testStringB] -- Loading EntityA -- EntityA{myIdA=1, refEntityB=EntityB{myIdB=3, str='testStringB'}} EntityA{myIdA=2, refEntityB=EntityB{myIdB=3, str='testStringB'}} -- Loading EntityB -- EntityB{myIdB=3, str='testStringB'}
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
|
|