Giới thiệu về JPA (Java Persistence API ) hay Jakarta Persistence trong Java

https://youtu.be/07GSHVeQbKo

Khi phát triển các ứng dụng Java, chúng ta thường cần lưu trữ dữ liệu vào cơ sở dữ liệu quan hệ như MySQL database, PostgreSQL database hoặc là Oracle database. Java cung cấp JDBC để ứng dụng có thể kết nối và làm việc với database. Tuy nhiên, khi ứng dụng trở nên lớn hơn, việc sử dụng JDBC trực tiếp có thể dẫn đến khá nhiều code lặp lại, đặc biệt là khi chúng ta phải chuyển đổi dữ liệu giữa các Java object và các record trong database.

Để giải quyết vấn đề này, các bạn có thể sử dụng JPA (Java Persistence API), hiện tại thì nó được gọi là Jakarta Persistence API, với ORM (Object-Relational Mapping) đó các bạn. JPA là một standard specification dành cho việc sử dụng các Java object để làm việc với relational database. Các bạn có thể sử dụng nó để mapping giữa Java object và các record trong database và cũng có thể sử dụng nó để truy vấn, thao tác với các record này. Cụ thể như thế nào? Trong bài viết này, chúng ta sẽ tìm hiểu JPA là gì, ORM là gì, JPA có vai trò như thế nào trong Java ecosystem và đặc biệt là sự khác nhau giữa JPA và Hibernate, các bạn nhé!

Để làm ví dụ cho bài viết này, mình sẽ tạo mới một Maven project:

Để làm việc với JPA thì các bạn có thể khai báo Jakarta Persistence API dependency như sau:

Vấn đề của việc lưu trữ Java Object vào Database

Giả sử bây giờ, mình có một class Student có nội dung như sau:

Trong database, mình có một table students với cấu trúc như sau:

Mình cũng đã insert sẵn một số example data như sau:

Trong ứng dụng Java, để lấy thông tin student từ table students này, chúng ta sẽ làm việc với Student object với các attribute là id, name, email. Còn trong database thì chúng ta sẽ làm việc với table students với các column là id, name và email. Đây chính là object-relational impedance mismatch — sự khác biệt giữa mô hình object-oriented của Java và mô hình relational của database đó các bạn.

Nếu sử dụng JDBC trực tiếp, chúng ta thường phải tự thực hiện nhiều công việc để chuyển đổi giữa hai mô hình này, ví dụ như sau:

Với một ứng dụng lớn thì kiểu code mapping như vậy có thể xuất hiện ở rất nhiều nơi. Do đó, việc sử dụng JPA với ORM sẽ giúp cho chúng ta làm việc dễ dàng hơn với database trong các ứng dụng Java đó các bạn.

ORM là gì?

ORM là viết tắt của Object-Relational Mapping.

Nó là kỹ thuật ánh xạ giữa các Java object trong ứng dụng Java và dữ liệu trong relational database.

Ví dụ như field id trong class Student có thể map với column id trong table students, field name có thể map với column name, field email có thể map với column email, …

ORM có thể giúp các bạn mô tả mapping này bằng cách sử dụng các annotation thay vì các bạn phải tự viết toàn bộ code để mapping.

Ví dụ các bạn có thể viết lại class Student sử dụng các annotation của JPA API như sau:

Trong ví dụ trên:

  • Student đại diện cho một persistent object.
  • @Entity xác định rằng class này là một entity.
  • @Table : nếu tên table trong database khác với tên entity, thì các bạn cần sử dụng annotation này để mapping nhé.
  • id được xác định là identity của entity thông qua @Id.

Các field của entity có thể được mapping tới các column trong database đó các bạn.

ORM chủ yếu cung cấp một abstraction để chúng ta có thể làm việc với persistence theo mô hình object-oriented.

JPA là gì?

JPA là viết tắt của Java Persistence API.

JPA là tên gọi được sử dụng trước đây cho specification về persistence trong Java. Ngày nay, specification này thuộc Jakarta EE và có tên chính thức là Jakarta Persistence nha các bạn.

JPA là một specification, không phải một implementation.

Specification này định nghĩa các API, annotation và behavior mà một persistence provider cần cung cấp.

Ví dụ, JPA định nghĩa các annotation như:

  • @Entity
  • @Id
  • @Table
  • @Column

và các API như:

  • EntityManager

Nhưng JPA không tự thực hiện việc kết nối và thao tác với database. Công việc đó sẽ được thực hiện bởi một JPA provider.

JPA Specification và JPA Implementation

Để hiểu JPA, các bạn cần phải phân biệt hai khái niệm:

  • Specification
  • Implementation

Một specification định nghĩa contract.

Implementation là phần mềm thực hiện contract đó.

Một số JPA provider phổ biến gồm:

  • Hibernate
  • EclipseLink
  • OpenJPA

Trong đó, Hibernate là implementation mà chúng ta thường gặp nhất trong các ứng dụng Java hiện đại.

Các bạn hãy nhớ:

  • JPA là specification.
  • Hibernate là một implementation của specification đó.

JPA và Hibernate khác nhau như thế nào?

Đây là một trong những điểm dễ gây nhầm lẫn nhất đối với những người mới học JPA.

Khi chúng ta viết:

@Entity là một annotation được định nghĩa bởi Jakarta Persistence.

Tương tự:

cũng thuộc Jakarta Persistence.

Những API và annotation này không phải riêng của Hibernate.

Hibernate là một implementation có khả năng hiểu và thực hiện các quy tắc được định nghĩa bởi Jakarta Persistence.

Các bạn có thể hình dung:

Application -> Jakarta Persistence API -> Hibernate (hoặc là EclipseLink hay OpenJPA) -> JDBC -> Database

Chúng ta có thể viết application dựa trên JPA API thay vì phụ thuộc trực tiếp vào Hibernate API trong phần lớn các trường hợp.

Những khái niệm cơ bản trong JPA

JPA cung cấp một số khái niệm quan trọng, bao gồm:

  • Entity
  • Persistence Context
  • EntityManager
  • Entity Lifecycle
  • Persistence Unit
  • JPA Provider

Entity

Entity là một Java object được quản lý bởi persistence mechanism và có thể được lưu trữ vào database.

Như ví dụ ở trên thì Student là một entity đó các bạn.

Entity thường đại diện cho một khái niệm dữ liệu trong application. Ví dụ như các bạn có thể định nghĩa các entity như sau trong một ứng dụng:

  • Student
  • Course
  • Employee
  • Department
  • Product
  • Order
  • Customer

Persistence Context

Persistence Context là một khái niệm rất quan trọng trong JPA. Các bạn có thể hiểu đơn giản rằng persistence context là một môi trường trong đó các entity instances được persistence provider quản lý.

Ví dụ như khi các bạn tạo nhiều instance cho entity Student thì Persistence Context nó sẽ nắm giữ thông tin của các instance này. Nhờ đó mà một entity nằm trong persistence context có thể được persistence provider theo dõi trạng thái của nó, đó các bạn.

EntityManager

EntityManager là một trong những API quan trọng nhất của Jakarta Persistence. Nó cung cấp các API để application có thể làm việc với entity và persistence context.

Một số operation phổ biến được cung cấp bởi EntityManager bao gồm:

  • persist(): entity sẽ được managed và sẽ được insert vào database
  • find(): tìm kiếm một entity bằng primary key của nó
  • merge(): copy trạng thái của một entity vào một entity đã được manage
  • remove(): đánh dấu một entity sẽ bị xóa
  • detach(): xóa entity khỏi persistence context
  • refresh(): reload trạng thái của entity từ database

Mình sẽ đi chi tiết các phương thức này sau các bạn nhé.

Entity lifecycle

Một entity có thể trải qua nhiều trạng thái khác nhau trong quá trình tồn tại. Các trạng thái chính thường được nhắc tới là:

  • New: một entity là New khi nó chỉ mới được tạo và chưa được quản lý bởi persistence context.
  • Managed: entity đã được quản lý bởi persistence context
  • Detached: entity trước đó đã được quản lý bởi một persistence context nhưng hiện tại đã bị remove ra khỏi persistence context đó.
  • Removed: khi entity bị đánh dấu là sẽ remove trong database.

Chúng ta có thể tìm hiểu chi tiết entity lifecycle và cách EntityManager tác động đến các trạng thái này trong các bài viết khác, các bạn nhé.

Persistence Unit

Persistence Unit là một tập hợp các persistence-related configurations và entity được quản lý cùng nhau.

Trong các ứng dụng Jakarta Persistence truyền thống, persistence unit thường được cấu hình thông qua tập tin persistence.xml. Persistence unit xác định các thông tin cần thiết cho persistence environment, chẳng hạn như persistence provider và database configuration.

Trong các framework hiện đại, các bạn có thể không trực tiếp làm việc với persistence.xmlnhưng khái niệm persistence unit vẫn là một phần quan trọng của Jakarta Persistence, đó các bạn.

Ví dụ JPA đơn giản

Bây giờ, chúng ta sẽ convert ví dụ trên bằng cách sử dụng Jakarta Persistence để xem cách làm việc với nó sẽ như thế nào, các bạn nhé!

Đầu tiên, các bạn cần thêm Hibernate dependency để làm phần implementation của Jakarta Persistence như sau:

hibernate-core dependency sẽ tự động include jakarta.persistence-api dependency nên các bạn không cần khai báo jakarta.persistence-api dependency nữa nhé.

Các bạn cần tạo mới tập tin Persistence Unit persistence.xml trong thư mục /src/main/resources/META-INF để định nghĩa thông tin về database và persistence provider như sau:

Như các bạn thấy, chúng ta sẽ định nghĩa thông tin về entity class và thông tin database bên trong thẻ <persistence-unit>
Bây giờ thì trước khi lấy đối tượng EntityManager để làm việc với các entity, chúng ta sẽ khởi tạo đối tượng của class EntityManagerFactory từ tập tin persistence.xml này như sau:

Các bạn chỉ cần truyền thông tin Persistence Unit name vào phương thức createEntityManagerFactory là được. Jakarta Persistence với Hibernate implementation sẽ đọc tập tin persistence.xml để tạo EntityManagerFactory cho chúng ta.

Sau khi đã lấy EntityManager từ EntityManagerFactory, các bạn có thể lấy thông tin student như sau:

Kết quả khi các bạn chạy ví dụ này như sau:

Như các thấy, chỉ với vài dòng code, chúng ta đã có thể lấy được thông tin của Student trong database rồi.

JPA và JDBC

JPA không thay thế JDBC theo nghĩa JDBC không còn tồn tại. Thay vào đó, JPA thường nằm ở abstraction level cao hơn JDBC nha các bạn.

Đây là bảng so sánh đơn giản giữa JPA và JDBC:

JDBC JPA
API để làm việc với database Specification cho persistence
SQL-centric Object-centric
Developer thường xử lý mapping thủ công ORM hỗ trợ mapping
Làm việc trực tiếp với JDBC API Làm việc thông qua persistence API
Không phải ORM Cung cấp ORM programming model

Với JDBC, chúng ta sẽ thường làm việc trực tiếp với:

  • Connection
  • PreparedStatement
  • ResultSet

Trong khi đó, với JPA, chúng ta sẽ làm việc với:

  • Entity
  • EntityManager
  • Persistence Context

JPA provider sau đó có thể sử dụng JDBC để giao tiếp với database.

Kết luận

JPA là một phần rất quan trọng trong Java persistence ecosystem. Ngày nay, JPA được gọi chính thức là Jakarta Persistence và đóng vai trò là một specification cho persistence trong Java.

Điều quan trọng nhất, các bạn cần nhớ là:

  • JPA = Specification
  • Hibernate = Implementation

JPA cung cấp một object-oriented persistence model dựa trên ORM, trong đó các Java object có thể được mapping với dữ liệu trong relational database.

Nhờ vậy mà chúng ta có thể làm việc với database dễ dàng hơn trong các ứng dụng Java đó các bạn.

3.7/5 - (3 bình chọn)

22 thoughts on “Giới thiệu về JPA (Java Persistence API ) hay Jakarta Persistence trong Java”

  1. Em khai báo persistence.xml như trên bài nhưng lại báo lỗi như thế này
    Feb 22, 2020 12:02:12 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
    INFO: HHH000204: Processing PersistenceUnitInfo [
    name: jpaexample
    …]
    Feb 22, 2020 12:02:12 PM org.hibernate.Version logVersion
    INFO: HHH000412: Hibernate Core {5.2.12.Final}
    Feb 22, 2020 12:02:12 PM org.hibernate.cfg.Environment
    INFO: HHH000206: hibernate.properties not found
    Exception in thread “main” java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
    at org.hibernate.boot.spi.XmlMappingBinderAccess.(XmlMappingBinderAccess.java:43)
    at org.hibernate.boot.MetadataSources.(MetadataSources.java:87)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.(EntityManagerFactoryBuilderImpl.java:208)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.(EntityManagerFactoryBuilderImpl.java:170)
    at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:76)
    at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:181)
    at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:129)
    at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:71)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:52)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at entity.Application.main(Application.java:8)

    Anh xem dùm em thử tại sao được ko ạ.

  2. Mình đang làm 1 bài kết nối hibernate thì bị lỗi này, bạn giúp mình với ????
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.example.demo.model.MyUserType.userTypeName
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1080) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
    at com.example.demo.DemoApplication.main(DemoApplication.java:10) [classes/:na]
    Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.example.demo.model.MyUserType.userTypeName
    at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:322) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1892) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:911) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:738) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:245) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:222) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:265) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:382) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336) ~[spring-orm-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
    … 16 common frames omitted

    Process finished with exit code 1

    1. Bạn cần xem lại cái này nhé “Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.example.demo.model.MyUserType.userTypeName”, xem thử bạn đang khai báo các relationship có chỗ nào chưa đúng ko nhé?
      Hoặc cũng có thể share cái class này lên mình xem thử.

      1. Class MyUser:
        package com.example.demo.model;

        import javax.persistence.*;
        import java.util.Set;

        @Entity
        @Table(name=”user”)
        public class MyUser {
        @Id
        @GeneratedValue
        @Column(name = “id”)
        private int userId;

        @Column(name = “name”)
        private String userName;

        @Column(name = “email”)
        private String userEmail;

        @Column(name = “salary”)
        private int userSalary;

        @ManyToOne
        @JoinColumn(name = “user_type_id”)
        private MyUserType userType;

        public int getUserId() {
        return userId;
        }

        public void setUserId(int userId) {
        this.userId = userId;
        }

        public String getUserName() {
        return userName;
        }

        public void setUserName(String userName) {
        this.userName = userName;
        }

        public String getUserEmail() {
        return userEmail;
        }

        public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
        }

        public int getUserSalary() {
        return userSalary;
        }

        public void setUserSalary(int userSalary) {
        this.userSalary = userSalary;
        }

        public MyUserType getUserType() { return userType; }

        public void setUserType(MyUserType userType) { this.userType = userType; }
        }
        Class MyUserType:
        package com.example.demo.model;

        import javax.persistence.*;
        import java.util.Set;
        import java.util.Collection;
        import java.util.List;
        import java.util.Map;
        import java.util.SortedSet;
        import java.util.SortedMap;

        @Entity
        @Table(name = “user_type”)
        public class MyUserType {
        @Id
        @Column(name = “user_type_id”)
        private int userTypeId;

        @Column(name = “user_type_name”)

        private List userList;

        @OneToMany(mappedBy = “myUserType”, cascade = CascadeType.ALL)
        @JoinColumn(name = “user_type_id”)

        private String userTypeName;

        public int getUserTypeId() { return userTypeId; }

        public void setUserTypeId(int userTypeId) { this.userTypeId = userTypeId; }

        public String getUserTypeName() { return userTypeName; }

        public void setUserTypeName(String userTypeName) { this.userTypeName = userTypeName; }

        }
        Một UserType thì có nhiều user (khóa ngoại tham chiếu đến: user_type_id) Mình chỉ mới tìm hiểu còn nhiều sai sót mong bạn giúp đỡ, cảm ơn bạn nhiều 😀

        1. @Column(name = “user_type_name”)

          private List userList;

          @OneToMany(mappedBy = “myUserType”, cascade = CascadeType.ALL)
          @JoinColumn(name = “user_type_id”)

          private String userTypeName;

          Cái này có vẻ không đúng? Bạn check lại chỗ này nhé!

  3. ok cho em hỏi lại tổng kết một làn cuối, hibernate ngoài đặc tả cho jpa nó còn đặc tả chỉ chính bản thân nó, jpa thì có đặc tả là hibernate or eclipse link or …. thì như trong bài này nó tự đặc tả cho chính nó phải ko anh (tại em thấy bài viết trươc anh nói là jpa như một interface mà interface thì ko có các hàm chi tiết của no mà chỉ để cho thằng khác implement và viết chi tiết lại)

    1. à sorry anh em chưa đọc kỹ, bài này là thằng jpa có đặc tả của nó là hibernate.
      tại bửa em thực tập bên tma thì dùng hibernate ko thấy cái gì liên quan đến file persistence.xml hóa ra là bên đó dùng hibernate đặc tả cho chính no. làm cho em rối tung mù xòe mấy phần này

  4. anh cho em hỏi. em có 2 bảng như sau
    User(Username, Password) Username là khóa chính
    UserInfo(Username, Fullname); Username là khóa chính và là khóa ngoài tham chiếu đến User.
    Vậy quan hệ này là OneToOne hay sao ạ.
    Và config như thế nào ạ

  5. anh có thể cho em xin skype của anh được không, em đang rất mơ hồ về mọi thứ nên cần anh giúp để vượt qua

  6. Anh cho em hỏi sao emcopy code y sì của anh luôn, có sửa lại (password, user, url cho phù hợp với mySQL của mình) nhưng chạy không được. Nó ko báo lỗi gì hết nhưng nó như kiểu rơi vào vòng lặp vô tận ấy, ko chạy tiếp được nữa. Mình debug thì nó bị ngay dòng đầu tiên này luôn :
    EntityManagerFactory emf = Persistence.createEntityManagerFactory(“jpaexample”);
    Và nó làm cái MySQL Workbench của mình bị treo luôn, tắt eclipse mới hết treo

    1. Có cách nào bạn gửi cái project bạn đang chạy cho mình không?
      Mình sẽ thử chạy lại project của bạn trên máy mình để xem thử bị gì.

  7. cho mình hỏi khi nào dùng EntityMangager (của JPA) và khi nào dùng Session (của hibernate) để truy xuất dữ liệu vậy bạn. Tại sao có loại này rồi còn phải có loại kia, và ở dự án thực tế hộ thường dùng cách nào, mình thấy khó phân biệt quá.

        1. Hibernate có 2 phiên bản: 1 phiên bản thì hiện thực các đặc tả của JPA sử dụng EntityManager để quản lý các tables và thao tác trên chúng.
          Phiên bản thứ hai là phiên bản của riêng nó, nghĩa là Hibernate cũng xây dựng một cách khác để quản lý database. Cách này thì chúng ta sẽ sử dụng Session để thao tác trên database.
          Em phải phân biệt cái này để khỏi bị nhầm lẫn nhé!

Add Comment