1. Table of Contents
- Introduction
- Getting Started
- Enterprise Applications
- Object Relational Mapping
- Collection Mapping
- Entity Manager
- Using Queries
- Java Persistence Query Language
- Criteria
- Advanced Object Relational Mapping
- Advanced Queries
- Advanced Topics
- XML Mapping Files
- Packaging and Deployment
- Testing
2. Database source table và target table nêu hiểu như thế nào?
Theo tài liệu https://en.wikibooks.org/wiki/Java_Persistence/OneToOne, aOneToOne
relationship has the data model mirror the object model, ==> source object has a pointer to the target object && database source table has a foreign key to the target table.=> bảng chứa foreign key là bảng source, và đối tượng chứa foreign key cũng sẽ là source object.
All relationships in Java and JPA are unidirectional, in that if a source object references a target object there is no guarantee that the target object also has a relationship to the source object. => Address class không nhất thiết phải có tham chiếu tới đối tượng lớp Employee.
Ví dụ có thông tin relationship và bảng dữ liệu sau:
EMPLOYEE (table)
EMP_ID | FIRSTNAME | LASTNAME | SALARY | ADDRESS_ID |
1 | Bob | Way | 50000 | 6 |
2 | Sarah | Smith | 60000 | 7 |
ADDRESS (table)
ADDRESS_ID | STREET | CITY | PROVINCE | COUNTRY | P_CODE |
6 | 17 Bank St | Ottawa | ON | Canada | K2H7Z5 |
7 | 22 Main St | Toronto | ON | Canada | L5H2D5 |
vì EMPLOYEE (table) chứa khóa ngoại ADDRESS_ID nên bảng EMPLOYEE là source table và bảng còn lại ADDRESS (table) là target table.
@Entity
public class Employee {
@Id
@Column(name="EMP_ID")
private long id;
...
@OneToOne(fetch=FetchType.LAZY)
@JoinColumn(name="ADDRESS_ID")
private Address address;
...
}
<entity name="Employee" class="org.acme.Employee" access="FIELD">
<attributes>
<id name="id">
<column name="EMP_ID"/>
</id>
<one-to-one name="address" fetch="LAZY">
<join-column name="ADDRESS_ID"/>
</one-to-one>
</attributes>
</entit
Example of an inverse OneToOne relationship annotations
@Entity
public class Address {
@Id
@Column(name = "ADDRESS_ID")
private long id;
...
@OneToOne(fetch=FetchType.LAZY, mappedBy="address")
private Employee owner;
...
}
Example of an inverse OneToOne relationship XML
<entity name="Address" class="org.acme.Address" access="FIELD">
<attributes>
<id name="id"/>
<one-to-one name="owner" fetch="LAZY" mapped-by="address"/>
</attributes>
</entity>
owner ở onetoone là lớp chứa khóa ngoại
owner của onetomany là lớp không chứa khóa ngoài - lớp phía 1
owner của manytoone là lớp chứa khóa ngoại - lớp phía nhiều (n)
Sự giống nhau của 3 loại trên là chỉ lớp owner(source) là chứa tham chiếu tới dữ liệu của phía target.
Còn lớp target không có chiều ngược lại, nghĩa là chỉ có dữ liệu của nó.
Những lớp chứa khóa ngoại sẽ loại bỏ trường làm khóa ngoại trong danh sách các field của lớp đó.
Trong manytomany relationship:
@ManyToMany(cascade = { CascadeType.ALL }) annotation is used for linking each record of Employee table with Event table and vice versa
@JoinTable(name = "EMPLOYEE_EVENT", joinColumns = { @JoinColumn(name = "EMPLOYEEID") }, inverseJoinColumns = { @JoinColumn(name = "EVENTID") }) is used to define the join table, here it is "EMPLOYEE_EVENT", which is connecting 2 columns ie; EMPLOYEEID belongs to employee table & EVENTID belongs to event table
lớp này chứa 1 tập hợp các đối tượng của lớp kia và ngược lại. Bảng chung phát sinh được tạo từ 1 khóa chính của 2 bảng có quan hệ m-n.
3. Chương 2 + 3: Getting Started & Enterprise Applications
- The entity identifier, then, is equivalent to the primary key in the database table that stores the entity state.
- To turn Employee into an entity, we first annotate the class with @Entity. This is primarily just a marker annotation to indicate to the persistence engine that the class is an entity.
- The second annotation that we need to add is @Id. This annotates the particular field or property that holds the persistent identity of the entity (the primary key) and is needed so the provider knows which field or property to use as the unique identifying key in the table.
- When an entity manager obtains a reference to an entity, either by having it explicitly passed in as an argument to a method call or because it was read from the database, that object is said to be managed by the entity manager.
The set of managed entity instances within an entity manager at any given time is called its persistence context. Only one Java instance with the same persistent identity may exist in a persistence context at any time. For example, if an Employee with a persistent identity (or id) of 158 exists in the persistence context, then no other Employee object with its id set to 158 may exist within that same persistence context.
- Summary of API Objects and Concepts
Persistence Unit
The configuration that describes the persistence unit is defined in an XML file called persistence.xml.
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="mysql-eclipselink"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/querydsl" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
</persistence>
The transaction-type attribute indicates that the persistence unit uses resource-level EntityTransaction instead of JTA transactions.
The chapter 2 was to instantiate an entity instance and use the entity manager to persist it in the database. After we inserted a new entity, we could retrieve it again and then remove it. We also made some updates and ensured that the changes were written back to the database.
Referencing Server Resources
The @Resource annotation is the catchall reference for Java EE resource types that don’t have dedicated annotations.
It is used to define references to resource factories, data sources, and other server resources. The @Resource annotation is also the simplest to define because the only additional element is resourceType, which allows you to specify the type of resource if the server can’t figure it out automatically. For example, if the field you are injecting into is of type Object, then there is no way for the server to know that you wanted a data source instead. The resourceType element can be set to javax.sql.DataSource to make the need explicit.
One of the features of the @Resource annotation is that it is used to acquire logical resources specific to the component type. This includes EJBContext implementations as well as services such as the EJB timer service. Without defining it as such, we used setter injection to acquire the EJBContext instance in Listing 3-10. To make that example complete, the @Resource annotation could have been placed on the setSessionContext()method.
Listing 3-15 revisits the example from Listing 3-10, this time demonstrating field injection with @Resource to acquire a SessionContext instance.
Listing 3-15. Injecting a SessionContext Instance
@Stateless
@EJB(name="audit", beanInterface=AuditService.class)
public class DeptService {
@Resource
SessionContext context;
AuditService audit;
@PostConstruct
public void init() {
audit = (AuditService) context.lookup("audit");
}
//
}
CDI Beans
What are CDI beans, anyway? A CDI bean is any class that qualifies for the CDI injection services, the primary requirement of which is simply that it be a concrete class. Even session beans can be CDI beans and thus qualify for CDI injection services, although there are some caveats about their lifecycle contexts.
Injection and Resolution
A bean may have its fields or properties be the target of injection if they are annotated by @javax.inject.Inject. CDI defines a sophisticated algorithm for resolving the correct type of object to inject, but in the general case, if you have a field declared of type X, then an instance of X will be injected into it. We can rewrite the example in Listing 3-10 to use simple managed CDI beans instead of EJBs. Listing 3-16 shows the use of the injection annotation on a field. The AuditService instance will get injected after the DeptService instance gets instantiated.
Listing 3-16. CDI Bean with Field Injection
public class DeptService {
@Inject AuditService audit;
// ...
}
The annotation could similarly be placed on a property method to employ setter injection. Yet another way to achieve the same result is to use a third kind of injection called constructor injection. As the name suggests, constructor injection involves the container invoking the constructor method and injecting the arguments. Listing 3-17 shows how constructor injection can be configured. Constructor injection is particularly good for testing outside of the container since a test framework can easily do the necessary injection by simply calling the constructor without having to proxy the object.
Listing 3-17. CDI Bean with Constructor Injection
public class DeptService {
private AuditService audit;
@Inject DeptService(AuditService audit) {
this.audit = audit;
}
// ...
}
The differences between the RI and DI are listed below.
a. Resource Injection can inject JNDI Resources directly whereas Dependency Injection cannot.
b. Dependency Injection can inject Regular Classes (managed bean) directly whereas Resource Injection cannot.
c. Resource Injection resolves by resource name whereas Dependency Injection resolves by type.
d. Dependency Injection is typesafe whereas Resource Injection is not.
4. Chapter 4 : Object relational mapping
Untyped MapsIf we did not want to (or were not able to) use the typed parameter version of Map<KeyType, ValueType>, we would define it using the non-parameterized style of Map shown in Listing 5-19.
Listing 5-19. One-to-Many Relationship Using a Non-parameterized Map
@Entity
public class Department {
// ...
@OneToMany(targetEntity=Employee.class, mappedBy="department")
@MapKey
private Map employees;
// ...
}
The targetEntity element only ever indicates the type of the Map value. Of course, if the Map holds an element collection and not a relationship, the targetClass element of @ElementCollection is used to indicate the value type of the Map.
targetEntity is the entity class that is the target of the association (relationship). If the collection-valued relationship property is defined using Java generics. Không nhầm lẫn với target object (cùng với source object) đã nêu trên.
5. Chapter 5 : Collection Mapping
6. Chapter 6 : Entity Manager
7. Chapter 7 : Using Queries
8. Query Language
9. Criteria API
10. Advanced Object-Relational Mapping
11. Advanced Queries
Rerefence:
Pro JPA 2, 2nd Edition.pdfMISC
@NotFound annotation to avoid exception in get entity
@ManyToOne(fetch=FetchType.LAZY)
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "MENU_ENTITY_ID", insertable = false, updatable = false)
public MenuEntity getMenu() {
return this.menu;
}
// bi-directional many-to-one association to RoleEntity
@ManyToOne(fetch=FetchType.LAZY)
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "ROLE_ENTITY_ID", insertable = false, updatable = false)
public RoleEntity getRoleEntity() {
return this.roleEntity;
}
0 comments:
Post a Comment