Wednesday, September 20, 2017

JavaEE: Tạo và Dùng RESOURCE LOCAL Trong Persistence.xml

Trong nhiều trường hợp ta muốn test dữ liệu tương tác với database của ta một cách nhanh chóng mà khồng cần phải deploy lên application server ta có thể sẽ cần dùng tới resource local và run như một junit test.
Ta tạo bất kì maven project với type maven-archetype-quickstart
Project ta sẽ có dạng như sau

project
  丨ㅡ src
  丨     丨― main
  丨     丨       丨― java
  丨     丨       丨― resources
  丨     丨                  丨― META-INF
  丨     丨―  test
  丨     丨       丨― java
  丨     丨       丨― resources

 pom.xml


Ta tạo file persistence.xml trong thư mục {project}/src/main/resource/META-INF với nội dung như sau.
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/persistence"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
 version="2.0">
 <persistence-unit name="JPATESTING" transaction-type="RESOURCE_LOCAL">
  <properties>
   <!-- JDBC CONFIG FOR H2 DB -->
   <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
   <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test" />
   <property name="javax.persistence.jdbc.user" value="sa" />
   <property name="javax.persistence.jdbc.password" value="" />
   <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
   
   <!-- JDBC CONFIG FOR POSTGRESQL DB -->
<!--    <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> -->
<!--    <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/test" /> -->
<!--    <property name="javax.persistence.jdbc.user" value="postgres" /> -->
<!--    <property name="javax.persistence.jdbc.password" value="postgres" /> -->
<!--    <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> -->
   
   <!-- JDBC CONFIG FOR MYSQL DB -->
<!--    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> -->
<!--    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test" /> -->
<!--    <property name="javax.persistence.jdbc.user" value="root" /> -->
<!--    <property name="javax.persistence.jdbc.password" value="" /> -->
<!--    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> -->
   
   <!-- JDBC CONFIG FOR SQL SERVER DB -->
<!--    <property name="javax.persistence.jdbc.driver" value="net.sourceforge.jtds.jdbc.Driver" /> -->
<!--    <property name="javax.persistence.jdbc.url" value="jdbc:jtds:sqlserver://localhost:1433/test" /> -->
<!--    <property name="javax.persistence.jdbc.user" value="sa" /> -->
<!--    <property name="javax.persistence.jdbc.password" value="mypass" /> -->
<!--    <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" /> -->
   
   
   <property name="hibernate.hbm2ddl.auto" value="create-drop" />
   <property name="hibernate.show_sql" value="true" />
   <property name="hibernate.format_sql" value="true" />
   <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
  </properties>
 </persistence-unit>
</persistence>
Chỉnh sửa file pom như sau
<?xml version="1.0"?>
<project
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <modelVersion>4.0.0</modelVersion>
 ....
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <hibernate.version>4.3.6.Final</hibernate.version>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
 </properties>
 <dependencies>
  <dependency>
   <groupId>javax</groupId>
   <artifactId>javaee-api</artifactId>
  </dependency>
  
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.11</version>
   <scope>test</scope>
  </dependency>
  
  <!-- JPA -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-entitymanager</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  
  <!-- For connection pooling -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-c3p0</artifactId>
   <version>${hibernate.version}</version>
  </dependency>
  
  <!-- h2 -->
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <version>1.4.192</version>
   <scope>test</scope>
  </dependency>
  
  <!-- mysql -->
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>6.0.6</version>
  </dependency>
  
  <!-- postgresql -->
  <dependency>
   <groupId>postgresql</groupId>
   <artifactId>postgresql</artifactId>
   <version>9.4.1208-jdbc42-atlassian-hosted</version>
  </dependency>
  
  <!-- for sql server connection -->
  <dependency>
      <groupId>net.sourceforge.jtds</groupId>
      <artifactId>jtds</artifactId>
      <version>1.3.1</version>
  </dependency>

 </dependencies>
</project>
Tạo 2 entity PersonEntity, AddressEntity như sau
AdressEntity
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "address")
public class AddressEntity {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;

 private String name;

 @ManyToOne
 @JoinTable(name = "person_address", joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id"))
 private PersonEntity person;

 public long getId() {
  return id;
 }

 public void setId(long id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public PersonEntity getPerson() {
  return person;
 }

 public void setPerson(PersonEntity person) {
  this.person = person;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((name == null) ? 0 : name.hashCode());
  result = prime * result + (int) (id ^ (id >>> 32));
  System.out.println("===========hashcode:" + result);
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  AddressEntity other = (AddressEntity) obj;
  if (name == null) {
   if (other.name != null)
    return false;
  } else if (!name.equals(other.name))
   return false;
  if (id != other.id)
   return false;
  return true;
 }

 @Override
 public String toString() {
  return "AddressEntity [id=" + id + ", name=" + name + "]";
 }
}
PersonEntity
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;

@Entity
@Table(name = "person")
public class PersonEntity {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private long id;

 private String name;

 @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
 @JoinTable(name = "person_address", joinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id", unique = true, nullable = true))
 @OrderBy("id ASC")
 private Set<AddressEntity> addresses;

 public long getId() {
  return id;
 }

 public void setId(long id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Set<AddressEntity> getAddresses() {
  return addresses;
 }

 public void setAddresses(Set<AddressEntity> addresses) {
  this.addresses = addresses;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((addresses == null) ? 0 : addresses.hashCode());
  result = prime * result + (int) (id ^ (id >>> 32));
  result = prime * result + ((name == null) ? 0 : name.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  PersonEntity other = (PersonEntity) obj;
  if (addresses == null) {
   if (other.addresses != null)
    return false;
  } else if (!addresses.equals(other.addresses))
   return false;
  if (id != other.id)
   return false;
  if (name == null) {
   if (other.name != null)
    return false;
  } else if (!name.equals(other.name))
   return false;
  return true;
 }

 @Override
 public String toString() {
  return "Person [id=" + id + ", name=" + name + ", addresses=" + addresses + "]";
 }

}
Cách get EntityManager
String PERSISTENCE_UNIT_NAME = "JPATESTING";
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();
Test case
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class PersonAddressTest {
 private static final String PERSISTENCE_UNIT_NAME = "JPATESTING";
 private static EntityManagerFactory factory;
 private static long companyId;

 @BeforeClass
 public static void setUp() throws Exception {
  System.out.println("===============init data");
  factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
  EntityManager em = factory.createEntityManager();

  em.getTransaction().begin();

  PersonEntity person = new PersonEntity();
  person.setName("Person A");

  Set<AddressEntity> addresses = new LinkedHashSet<AddressEntity>();
  AddressEntity address = new AddressEntity();
  address.setName("Address A");

  AddressEntity address1 = new AddressEntity();
  address1.setName("Address B");

  AddressEntity address2 = new AddressEntity();
  address2.setName("Address C");

  addresses.add(address);
  addresses.add(address1);
  addresses.add(address2);
  person.setAddresses(addresses);
  em.persist(person);
  companyId = person.getId();

  em.getTransaction().commit();
  em.close();
  System.out.println("===============end init data");
 }

 @Test
 public void testFunction1() {
  System.out.println("=============begin function 1");
  EntityManager em = factory.createEntityManager();
  em.getTransaction().begin();

  PersonEntity person = em.find(PersonEntity.class, companyId);
  Assert.assertEquals(person.getName(), "Person A");
  Assert.assertEquals(person.getAddresses().size(), 3);

  List<AddressEntity> addresses = new ArrayList<>(person.getAddresses());
  System.out.println(addresses);
  Assert.assertEquals(addresses.get(0).getName(), "Address A");
  Assert.assertEquals(addresses.get(1).getName(), "Address B");
  Assert.assertEquals(addresses.get(2).getName(), "Address C");

  System.out.println("*************************************");
  person = em.find(PersonEntity.class, companyId);

  Set<AddressEntity> addresses2 = person.getAddresses();
  addresses2.removeIf(address -> address.getId() == 2 || address.getId() == 3);

  AddressEntity address = addresses2.iterator().next();
  address.setName("Address D");
  address.setPerson(null);

  AddressEntity address1 = new AddressEntity();
  address1.setName("Address E");
  address1.setPerson(null);

  AddressEntity address2 = new AddressEntity();
  address2.setName("Address F");
  address2.setPerson(null);

  addresses2.add(address1);
  addresses2.add(address2);
  person.setAddresses(addresses2);
  // person.getAddresss().clear();
  // person.getAddresss().addAll(addresses2);
  em.merge(person);

  em.getTransaction().commit();
  em.close();
  System.out.println("==================end function 1");
 }

 @Test
 public void testFunction2() {
  EntityManager em = factory.createEntityManager();

  em.getTransaction().begin();
  PersonEntity person = em.find(PersonEntity.class, companyId);
  Assert.assertEquals(person.getName(), "Person A");
  Assert.assertEquals(person.getAddresses().size(), 3);

  List<AddressEntity> addresses = new ArrayList<>(person.getAddresses());
  System.out.println(addresses);
  Assert.assertEquals(addresses.get(0).getName(), "Address D");
  Assert.assertEquals(addresses.get(1).getName(), "Address E");
  Assert.assertEquals(addresses.get(2).getName(), "Address F");

  person = em.find(PersonEntity.class, companyId);

  List<AddressEntity> addresses2 = person.getAddresses().stream().collect(Collectors.toList());
  addresses2.removeIf(address -> address.getId() == 4 || address.getId() == 5);

  AddressEntity address = addresses2.iterator().next();
  address.setName("Address G");
  address.setPerson(null);

  AddressEntity address1 = new AddressEntity();
  address1.setName("Address H");
  address1.setPerson(null);

  AddressEntity address2 = new AddressEntity();
  address2.setName("Address J");
  address2.setPerson(null);

  addresses2.add(address1);
  addresses2.add(address2);
  // person.setAddresss(addresses2);
  person.getAddresses().clear();
  person.getAddresses().addAll(addresses2);
  em.merge(person);
  em.getTransaction().commit();
  em.close();
 }

 @Test
 public void testFunction3() {
  EntityManager em = factory.createEntityManager();

  em.getTransaction().begin();
  PersonEntity person = em.find(PersonEntity.class, companyId);
  Assert.assertEquals(person.getName(), "Person A");
  Assert.assertEquals(person.getAddresses().size(), 3);

  List<AddressEntity> addresses = new ArrayList<>(person.getAddresses());
  System.out.println(addresses);
  Assert.assertEquals(addresses.get(0).getName(), "Address G");
  Assert.assertEquals(addresses.get(1).getName(), "Address H");
  Assert.assertEquals(addresses.get(2).getName(), "Address J");

  em.getTransaction().commit();
  em.close();
 }
}
Tham khảo 
https://stackoverflow.com/questions/3585544/how-to-configure-hibernate-config-file-for-sql-server

No comments:

Post a Comment