220 likes | 410 Views
قسمتهای خوب JPA و Hibernate. امیر مقیمی مهندس نرم افزار، شرکت Veda، استرالیا. مقدمه. ابزار Hibernate و استاندارد JPA: برای اتصال به پایگاه داده های رابطه ای در جاوا طراحی شده اند بی مقدمه می رویم سر اصل مطلب: تعریف یک Entity عملیات CRUD : Create Retrieve Update Delete. Entity.
E N D
قسمتهای خوب JPA و Hibernate امیر مقیمی مهندس نرم افزار، شرکت Veda، استرالیا
مقدمه • ابزار Hibernate و استاندارد JPA: • برای اتصال به پایگاه داده های رابطه ای در جاوا طراحی شده اند • بی مقدمه می رویم سر اصل مطلب: • تعریف یک Entity • عملیات CRUD: Create Retrieve Update Delete
Entity importjavax.persistence.*;@Entitypublicclass Employee { @Idprivatelong id; privateString firstName;privateString lastName; // getters and setters // Never put annotations on getters @Idpubliclong getId() { return id; }}
Create/Update EntityManager em= getEntityManager();Employee employee =new Employee();employee.setFirstName("Bob");employee.setLastName("Dylan"); employee =em.merge(employee); // Never use merge without assignment of return value em.merge(employee); // Never use persist em.persist(employee);
Retrieve/Delete EntityManager em= getEntityManager();Employee employee =em.find(Employee.class, id); em.remove(employee);
Transactions // Never create EntityManager or EntityManagerFactory yourself EntityManager em =createEntityManager(); Employee detached= em.find(Employee.class, id); // Never close EntityManager yourself em.close();EntityManager newEm =createEntityManager(); // Never manage (begin/commit/rollback) transactions using EntityManager newEm.getTransaction().begin();Employee managed = newEm.merge(detached);newEm.getTransaction().commit();
Detached vs Managed • Managed: • A managed object is the one read in the current persistence context (EntityManager/JTA transaction). • The persistence context will track changes to every managed object and maintain its object identity. • If the same object is read again, in the same persistence context, or traversed through another managed object's relationship, the same identical (==) object will be returned. • Calling persist() on a new object will also make it become managed. • Calling merge() on a detached object will return the managed copy of the object. • An object should never be managed by more than one persistence context. • An object will be managed by its persistence context until the persistence context is cleared through clear(), or the object is forced to be detached through detach(). • A removed object will no longer be managed after a flush() or commit(). • On a rollback, all managed objects will become detached. In a JTA managed EntityManager all managed objects will be detached on any JTA commit or rollback. http://en.wikibooks.org/wiki/Java_Persistence/Persisting
Detached vs Managed • Detached: • A detached object is one that is not managed in the current persistence context. • This could be an object read through a different persistence context, or an object that was cloned or serialized. • A new object is also considered detached until persist() is called on it. • An object that was removed and flushed or committed, will become detached. • An object could be considered both managed in the context of one persistence context, and detached in the context of another persistence context. • A managed object should only ever reference other managed objects, and a detached object should only reference other detached objects. • Incorrectly relating managed and detached objects is one of the most common problems users run into in JPA. http://en.wikibooks.org/wiki/Java_Persistence/Persisting
Even 2 more states! http://openjpa.apache.org/builds/2.3.0/apache-openjpa/docs/manual.html
Best Practice • Always assume an object is detached/new unless found/merged in the same method • Make it managed as soon as possible • Only set/add managed objects into each other • Never use Cascade
Relationships @Entitypublicclass Phone { @Idprivatelong id;privateString number; // Never ever use eager!! @ManyToOne @ManyToOne(fetch=FetchType.EAGER) @ManyToOne(fetch=FetchType.LAZY)// @JoinColumn(name="OWNER_ID")private Employee owner;}
Other Relationships @Entitypublicclass Employee { @Idprivatelong id; ...// Never use @OneToMany @OneToManyprivateList<Phone> phones; ...}
Other Relationships @Entitypublicclass Employee { @Idprivatelong id; ...// Never use @ManyToMany @ManyToManyprivateList<Project> projects; .....}
Inheritance @MappedSuperclasspublicabstractclass Project { @Idprivatelong id; @Column(name="NAME")privateString name; ...} @Entity@Table(name="LARGEPROJECT")@AttributeOverride(name="name", column= @Column(name="PROJECT_NAME"))publicclass LargeProject extends Project {privateBigDecimal budget;} @Entity@Table("SMALLPROJECT")publicclass SmallProject extends Project {}
Inheritance • Never use @Inheritance @Entity@Inheritance(strategy=InheritanceType….) • Just use @MappedSuperclass if OO inheritance is required
Querying Query query = em.createQuery("select e from Employee e where e.name = :name");query.setParameter("name", "Bob Dylan"); // Do NOT execute this without a very restrictive where condition List<Employee> employees = query.getResultList(); Query query = em.createQuery("select e from Employee e order by e.birthDate");query.setFirstResult(100);query.setMaxResults(200);// Now it is safe to execute this because we have pagination in place List<Employee> page = query.getResultList();
Advanced Queries // When you need address for all of the queried employees (This is to avoid infamous N+1 queries!) SELECT e FROM Employee e JOINFETCHe.address // Do NOT write it like this (it does not instantiate relationships; so, e.address will not be loaded!): SELECT e, a FROM Employee e, Address a WHERE e.address = a // To include employees with no address (null address field) SELECT e FROM Employee e LEFTOUTERJOINFETCH e.address
موضوعاتی برای آینده • EntityManager/Session management • LazyInitializationException !!! • Transaction management • OneToOne • XToMany alternatives • Bulk update/delete • Hibernate Caching: First/Second/Query level
موضوعاتی برای آینده • Criteria API • Advanced proxy details: • instanceof issues • accessing id for lazy entities • Equals and hashCode for Entity • The good, the bad, the ugly: Native SQL queries • DDL support (schema creation and migration) • Hibernate/JPA alternatives! • Specifically jOOQ