Kick Start Jpa
-
Upload
stephan-janssen -
Category
Technology
-
view
4.584 -
download
0
Transcript of Kick Start Jpa
![Page 1: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/1.jpg)
KICK START JPAAlexander Snaps – Axen
![Page 2: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/2.jpg)
GOAL OF THE PRESENTATION
give a good overview of the Java Persistence API (JPA),while still addressing more advanced issues & common pitfalls
all you need to successfully start with JPA
![Page 3: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/3.jpg)
So... You are still not using JavaEE 5 ?
Still believe JDBC is fun ?Still stuck with a RDBMS ?
![Page 4: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/4.jpg)
try { Connection connection = DriverManager.getConnection("jdbc:derby:Console;create=true"); Statement statement = null; try { statement = connection.createStatement(); statement.execute("SELECT first_name, last_name FROM persons"); ResultSet resultSet = null; try { resultSet = statement.getResultSet(); while(resultSet.next()) { String fName = resultSet.getString("first_name"); System.out.println(resultSet.wasNull ? "(null)" : fName); } } catch (SQLException e) { // Handle exception thrown while retrieving the result } finally { if(resultSet != null) resultSet.close(); } } catch (SQLException e) { // Handle exception thrown while trying to get to the database } finally { if(statement != null) statement.close(); connection.close(); }} catch (SQLException e) { // Handle exception thrown while trying to get a connection}
![Page 5: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/5.jpg)
• Eliminates the need for JDBC
• CRUD & Querying
• Object identity management
• Inheritance strategies
• Class hierarchy to single or multiple tables
• Associations, Composition
• Lazy navigation
• Fetching strategies
OBJECT RELATIONAL MAPPING
![Page 6: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/6.jpg)
INTRODUCING JPA• Vendor independent ORM solution
• Easily configurable
• Configuration directly in code using Java 5 annotations
• Configuration fine tunable, overriding annotations using XML
• Available outside JavaEE containers
• Dedicated Java Specification RequestJSR 317 as of JPA 2.0
![Page 7: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/7.jpg)
• One last thing on ORM
”The effective use of ORM technology in all but the simplest of enterprise environments requires
understanding and configuring how the mediation between relational data and objects is performed”
Linda DeMichiel Lead Architect EJB, Sun
It should all be ... transparent!:
![Page 8: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/8.jpg)
MAPPINGS
![Page 9: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/9.jpg)
• Transparent yet:
• Non-final class or methods
• Constructor with no argument
• Collections typed to interfaces
• Associations aren’t managed for you
• Database identifier field
JPA – BACK TO POJOS
![Page 10: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/10.jpg)
SIMPLEST ENTITY EXAMPLE@Entitypublic class Person { @Id
private Long ssn; private String firstName;
private String lastName; protected Person() {}
public Person(Long ssn, String firstName, String lastName) {
...
}}
![Page 11: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/11.jpg)
SIMPLE STILL, BUT VERBOSE@Entity(name = “Humans”)@Table(name = “persons”, schema = “hr”)public class Person {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Basic private Long ssn; private String firstName;
@Column(name = "NAME", unique = false, nullable = false, length = 255)
private String lastName;
protected Person() {}
public Person(Long ssn, String firstName, String lastName) {
...
}}
![Page 12: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/12.jpg)
SIMPLE TYPES• Primitives & wrapper classes !
• java.lang.String !
• java.math.BigInteger & BigDecimal
• Byte & Character arrays
• Java & JDBC Temporal types
• Enumeration
• Serializable types
![Page 13: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/13.jpg)
CLASS HIERARCHIES
• Entities support
• Inheritance
• polymorphic associations
• Concrete and abstract can be mapped
• @Entity
• @MappedSuperclass
![Page 14: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/14.jpg)
POLYMORPHISM
• Three mapping strategies
• One table per class hierarchy
• Joined subclass
• One table per concrete class (optional)
![Page 15: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/15.jpg)
MANY-TO-ONE ASSOCIATIONS
@Entitypublic class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long ssn; private String firstName; private String lastName;
private Company company; protected Person() {}
public Person(Long ssn, String firstName, String lastName) {
...
}}
@JoinColumn(name = “ID_COMP”) @ManyToOne
![Page 16: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/16.jpg)
MANY-TO-ONE ASSOCIATIONS
Person
- id: Long
- ssn: Long
- firstName: String
- lastName: String
Company
- id: Long
- name: String1
FK1
ssn
firstname
lname
company_id
PK id
person
name
PK id
company
![Page 17: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/17.jpg)
ONE-TO-ONE ASSOCIATIONS
@Entitypublic class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long ssn; private String firstName; private String lastName;
@OneToOne private AccessPass accessPass; protected Person() {}
public Person(Long ssn, String firstName, String lastName) {
...
}}
![Page 18: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/18.jpg)
ONE-TO-ONE ASSOCIATIONS
Person
- id: Long
- ssn: Long
- firstName: String
- lastName: String
AccessPass
- id: Long
- validUntil: Date0..1
FK1
ssn
firstname
lname
access_id
PK id
person
until
PK id
access
![Page 19: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/19.jpg)
ONE-TO-ONEBI-DIRECTIONAL
@Entitypublic class AccessPass { @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Temporal(TemporalType.DATE) private Date validUntil; @OneToOne(mappedBy=”accessPass”) private Person owner;
protected AccessPass() {}
public Person(Person person, Date validUntil) {
this.person = person; this.validUntil = (Date) validUntil.clone(); }}
![Page 20: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/20.jpg)
ONE-TO-MANYBI-DIRECTIONAL
@Entitypublic class Person {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = ”resident”) private Set<Address> addresses = new HashSet<Address>();
protected Person() {} }
![Page 21: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/21.jpg)
ONE-TO-MANYBI-DIRECTIONAL
@Entitypublic class Address {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; @ManyToOne @JoinColumn(name = “resident_id”) private Person resident;
public Address() {}
public void setResident(Person resident) { if(this.resident != resident) { if(this.resident != null) resident.removeAddress(this); this.resident = resident;
if(resident != null) resident.addAddress(this); } } }
![Page 22: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/22.jpg)
ONE-TO-MANYBI-DIRECTIONAL
@Entitypublic class Person { ...
@OneToMany(mappedBy = ”resident”) private Set<Address> addresses = new HashSet<Address>();
public void addAddress(Address address) { if(!this.addresses.contains(address)) { this.addresses.add(address); address.setResident(this); } }
public void removeAddress(Address address) { if(this.addresses.contains(address)) { this.addresses.remove(address); address.setResident(null); } } }
![Page 23: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/23.jpg)
ONE-TO-MANYUNI-DIRECTIONAL
• Same as the bi-directional only without the mappedBy
• Without a owning side with cardinality of one, a join table is required!
FK1
FK2
person_id
address_id
person_address
...
PK id
address
...
PK id
person
• With a unique constraint on FK2
• Many-to-Many is equal to One-to-Many uni-directional, but without the unique constraint
![Page 24: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/24.jpg)
*-TO-MANY EXAMPLES
@Entitypublic class Person { ... @OneToMany private Set<Address> addresses = new HashSet<Address>();
@ManyToMany(cascade = CascadeType.ALL) private Set<Project> projects = new HashSet<Project>();
... @OneToMany(mappedBy = “owner”) @MapKey(name = “type”) private Map<String, PhoneNumber> phones = new HashMap<String, PhoneNumber>();}
![Page 25: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/25.jpg)
USING JPA ENTITIES
![Page 26: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/26.jpg)
MANAGING PERSISTENCE
• javax.persistence.Persistence creates an EntityManagerFactory based on a persistence unit name
• With the EntityManagerFactory instance,you create EntityManager instances
• EntityManager to handle the persistence of your entities
• EntityTransaction used for transaction demarcation
• Query to... query(!) them back from the database
![Page 27: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/27.jpg)
SETTING UPTHE PERSISTENCE UNIT
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="myPU">
<jta-data-source> jdbc/myIncredibleDS </jta-data-source>
</persistence-unit>
</persistence>
![Page 28: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/28.jpg)
SETTING UPTHE PERSISTENCE UNIT
<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
<provider> oracle.toplink.essentials.PersistenceProvider </provider> <class>some.domain.Class</class> <properties> <property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/> <property name="toplink.jdbc.url" value="jdbc:derby:myData;create=true"/> <property name="toplink.ddl-generation" value="create-tables"/> </properties>
![Page 29: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/29.jpg)
DEPENDENCY INJECTION@Statelesspublic class EmployeeDaoBean implements EmployeeDao {
@PersistenceContext(unitName = “myPU”) private EntityManager em;
public Person getEmployee(Long ssn) { return em.find(Person.class, ssn); }}
![Page 30: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/30.jpg)
THE ENTITYMANAGER
• EntityManager.remove(Object): void
• EntityManager.find(Class<T>, Object): T
• EntityManager.persist(Object): void
• Manages CRUD operations
• Now how do I update ?
• You DO NOT!
• Manages object identity
![Page 31: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/31.jpg)
ENTITY LIFE-CYCLE
![Page 32: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/32.jpg)
THE LIFE-CYCLE• An entity can be described to be in four states
• Removed: the entity has a persistent identity & is associated to a persistence context, but scheduled for removal.
• Detached: the entity has a persistent identity, but is not (anymore) associated to a persistence context;
• Managed: the entity instance is associated to a persistence context;
• New: the entity instance is new and not yet associated to a persistence context;
![Page 33: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/33.jpg)
PERSISTING AN ENTITY
• The operation EntityManager.persist(Object) will have a new entity instance to become managed;
• Other entities referenced by the entity, whose association are to be cascaded when persisting, will also be persisted;
• If already managed, the operation will be ignored, but might be cascaded to other entities referenced by it.
• Yet, this might not happen as you call persist on the entity!
![Page 34: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/34.jpg)
REMOVING AN ENTITY
• You schedule the removal of an entity by calling EntityManager.remove(Object) operation
• If the entity is new or already scheduled for removal, the operation is ignored
• Again the operation might be cascaded
• Actual delete can be the result of the transaction committing or an explicit flush() of the persistence context
![Page 35: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/35.jpg)
MANAGED ENTITIES• A managed entity will have its state automatically synchronized
with the database.
• This operation, called flushing, depends on the flush mode
• Auto, or• Commit
• In the FlushModeType.COMMIT, the entity’s state will only be synchronized when the transaction actually commits
• This is not the default behavior of a PersistenceContext
![Page 36: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/36.jpg)
AUTO FLUSH MODE
• In the FlushModeType.AUTO, the entity’s state will still be synchronized to the database at the latest when the transaction commits or when ...
• A transaction is active and
• Either you flush with EntityManager.flush();
• or an operation requires the state to be synched.
![Page 37: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/37.jpg)
SOME EXAMPLE
![Page 38: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/38.jpg)
public void methodWithTxDemarcation() {
// loads Company named Apple Computers Company company = em.find(Company.class, "AAPL"); company.setName("Apple Inc.");
}
Query query = em.createQuery("select c from Companies"); List list = query.getResultList();
Company newCompany = new Company("Sun Microsystems", "JAVA"); em.persist(newCompany);
@PersistenceContextprivate EntityManager em;
![Page 39: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/39.jpg)
@Stateful@TransactionAttribute(NOT_SUPPORTED)public class StatefulBean {
public void createTheSun() {
}
public List<Company> query() {
return list; }
@TransactionAttribute(REQUIRED)@Removepublic void done() {}
}
Query query = em.createQuery("select c from Companies"); List list = query.getResultList();
Company newCompany = new Company("Sun Microsystems", "JAVA"); em.persist(newCompany);
@PersistenceContextprivate EntityManager em;
(type = EXTENDED)
![Page 40: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/40.jpg)
DETACHED ENTITIES• An entity is detached when
• its persistence context is closed;
• In a JavaEE environment, defaults when the transaction commits;
• In a JavaSE environment,you manage the persistence context’s life-cycle.
• the entity is serialized;
• an exception occurred !
![Page 41: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/41.jpg)
MERGINGDETACH ENTITIES BACK
• You can merge an entity back with a persistent context using EntityManager.merge(Object): Object
• If entity is detached, a new managed instance of the entity is returned, with the detached copied into it;
• If the entity is new, a new managed entity is returned, after have the state copied into it;
• Again, cascading applies;
• If the entity is scheduled for removal, an Exception is thrown.
![Page 42: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/42.jpg)
OPTIMISTIC LOCKING• To enable optimistic locking on an entity,
simply annotate an entity field with @Version
• The version attribute will be updated by the EntityManager every time the entity’s state is written to the database
• Field can be of type : int, Integer, short, Short, long, Long, Timestamp
• Apply it consistently to graphs
• Do not modify it...
• Throws OptimisticLockException
![Page 43: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/43.jpg)
QUERIES & BULK OPERATIONS
![Page 44: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/44.jpg)
JPA QUERY LANGUAGE• The Query API
• is used for
• named queries • dynamic queries
• supports
• polymorphism• named parameters• pagination
![Page 45: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/45.jpg)
DYNAMIC QUERIES
em.createQuery( "SELECT c FROM Customer c WHERE c.name" + " LIKE :custName") .setParameter("custName", name) .setFirstResult(10) .setMaxResults(10) .getResultList();
![Page 46: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/46.jpg)
STATIC QUERIES
@NamedQuery( name ="findAllCustomersWithName", query="SELECT c FROM Customer c WHERE c.name LIKE :custName")
![Page 47: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/47.jpg)
BULK OPERATIONS• You can bulk update & delete operations
with the Query API
• Delete example:DELETE FROM Customer c WHERE c.status = ‘inactive’
• Update example:UPDATE customer c SET c.status = ‘outstanding’ WHERE c.balance < 10000 AND 1000 > (SELECT COUNT(o) FROM customer cust JOIN cust.order o)
![Page 48: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/48.jpg)
BULK OPERATIONS
Caution !Bulk operation will not affect the EntityManager !!!
![Page 49: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/49.jpg)
OBJECT IDENTITYVS.
DATABASE IDENTITY
![Page 50: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/50.jpg)
OBJECT IDENTITY• How do you deal with object equality ?
• Introduce the database identifier as part of it ?
• Quick reminder from java.lang.Object#equals(Object)
Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.
![Page 51: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/51.jpg)
OBJECT IDENTITY • So that if the database identifier is in it,
you always have to have it assigned before using it in a Collection for instance
Company company = new Company(“JoGoSlow”);
em.persist(company);
em.flush();
group.addCompany(company);
![Page 52: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/52.jpg)
OBJECT IDENTITY• Other possible solutions
• Have real business key
• Have some sort of GUID / UUID
• Do not override equals(Object) nor hashCode()except if you real need to & know what you are doing !
• Yet that isn’t okay if your object is to be used as composite identifier
![Page 53: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/53.jpg)
JPA IN A JAVA EE ENVIRONMENT
![Page 54: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/54.jpg)
GETTING AN ENTITYMANAGER
• In JavaEE
• Using dependency injection:@PersistenceContext EntityManager em;
• Within a SFSB@PersistenceContext(type=PersistenceContextType.EXTENDED) EntityManager orderEM;
• Getting the EntityManagerFactory@PersistenceUnit EntityManagerFactory emf;
![Page 55: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/55.jpg)
EXTENDEDPERSISTENCE CONTEXT
• To be used within a Stateful SessionBean
• The persistence context will be created,when the SFSB is himself created
• And will be closed when the SFSB and all other SFSB that inherited the Persistence Context have been removed
• If the SFSB uses container-managed transaction demarcation, the persistence context will join the tx
![Page 56: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/56.jpg)
JPA 2.0aka. JSR 317
![Page 57: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/57.jpg)
MORE FLEXIBLE MODELING AND MAPPING
• Collections of basic types
• Improved support for embeddable classes
• Ordered lists
• Generalized maps
• Expanded relationship mapping options
• More flexible use of access types
![Page 58: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/58.jpg)
CRITERIA APICriteria crit = new Criteria(User.class) .project(Name.class) .property("firstName") .property("lastName") .orderBy() .property("lastName").asc() .property("firstName").asc() .property("age").desc() .restrict() .property("name").eq("Gavin") .and() .property("age").gt(18) .fetch("dependents").leftJoin() .join("address") .restrict() .property("country").in("USA", "AUSTRALIA");
em.createQuery(crit).getResultList();
![Page 59: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/59.jpg)
WELL ...
![Page 60: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/60.jpg)
SUMMARY
• JPA makes dealing with RDBMS simpler
• ... once you’ve understood how it works!
• It is available in JavaEE and JavaSE
• Multiple vendors
• On going dedicated JSR with lots of improvement on its way
• Great tool support
![Page 61: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/61.jpg)
CONCLUDING STATEMENTSo you think you want to forget about JDBC ?
The Java Persistence API looks cool ?It all can be yours today... and with great tooling !
![Page 62: Kick Start Jpa](https://reader034.fdocuments.net/reader034/viewer/2022051015/554f75ffb4c9058a148b55e8/html5/thumbnails/62.jpg)
& answers?Questions