ทำความรู้จักกับ EntityManager

ใน JPA Spec มีรูปแบบ EntityManager หรือ Persistence Context ไว้หลายแบบประกอบด้วย

  • ชนิดของ Persistence Context
    • Extended
    • Transaction
  • การจัดการกับ EntityManager
    • Container Managed
    • Application Managed
  • ชนิด Transaction ของ EntityManager
    • RESOURCE_LOCAL
    • JTA

อ่าน spec ได้จาก JSR 220 Specification

จากองค์ประกอบด้านบนจะมีบางอย่างเท่านั้นที่ใช้ได้ใน Java EE และเช่นกันจะมีบางอย่างเท่านั้นที่ใช้ได้ใน Java SE โดยในบทความนี้ผมจะยกข้อแตกต่างของแต่ละแบบเปรียบเทียบกัน…

Extended vs Transaction Persistence Context Type
Persistence Context type เป็นหนึ่งฟีเจอร์ของ EntityManager โดยค่าดีฟอลต์แล้วจะเป็น Transactional ใช้สำหรับการแก้ไข หรือ flush managed bean (managed bean คือ bean ที่ยังอยู่ใน scope ของ transaction และ bean นั้นจะถูกบันทึกการเปลี่ยนแปลงจนกว่า transaction จะ commit และหลังจาก transaction commit แล้วเราจะเรียกสถานะของ bean นั้นว่า detatched ซึ่งการเปลี่ยนแปลงค่าของ bean จะไม่มีผลกับ Persistence Context อีก)

ส่วน Extended นั้นจะใช้ได้กับ Stateful EJB(SFSB = Stateful Session Bean) เท่านั้น เพราะ SFSB ต้องมี state ซึ่งหลังจากจบ method แล้วไม่ได้หมายความว่าต้องจบ Transaction ด้วย

แต่สำหรับ SLSF(Stateless Session Bean) นั้นต่างออกไปเมื่อเราจบ business method แล้ว transaction ควรสิ้นสุดลง เพราะเมื่อเราเรียก method นั้นใหม่เราต้องทำการใช้ EJB instance ตัวใหม่ ซึ่งทำให้ หนึ่ง Method จึงเท่ากับหนึ่ง Transaction ดังนั้น SLSB จึงใช้ได้เฉพาะ Transaction type เท่านั้น

ข้อมูลเพิ่มเติมของ Persistence Context type อ่านได้จาก JSR 220 ใน JSR-000220 Enterprise JavaBeans 3.0 Final Release (persistence) หัวข้อที่ 5.6.1 และ 5.6.2

Persistence Context Type เราสามารถเลือก type ได้ตอนที่ EntityManager ถูก inject เข้ามาโดยเราสามารถเขียนโค๊ด

@PersistenceContext(type=javax.persistence.PersistenceContextType.EXTENDED)
EntityManager em;

ซึ่ง default ถ้าเราไม่กำหนดจะมี type เป็น javax.persistence.PersistenceContextType.TRANSACTION

โดยการใช้งาน Persistence Context Type จะใช้งานได้เมื่อเป็น Container Managed EntityManager เท่านั้น ในกรณีของ Application managed EntityManager จะแตกต่างออกไป สามารถอ่านเพิ่มเติมได้จากหัวข้อ 5.7 ของ JSR-000220 Enterprise JavaBeans 3.0 Final Release (persistence)

Container Managed vs Application Managed
โดยปกติแล้วเรามักจะทำการ inject EntityManager โดยใช้ @PersistenceContext เช่น

@PersistenceContext
EntityManager em;

โดยการเขียนแบบข้างบนเป็นการบอกให้ Container Inject EntityManager มาให้เรา นั้นหมายความว่าการเรียกใช้งานแบบนี้เป็น Container Managed EntityManager 😛

แต่ในทางกลับกัน ถ้าเราสร้าง EntityManager ขึ้นมาเองจาก EntityManagerFactory

@PersistenceUnit
EntityManagerFactory emf;
...
emf.createEntityManager();
...

ซึ่งวิธีนี้เราจะได้ EntityManager จากการเรียกใช้ method createEntityManager() และวิธีการนี้เองเราเรียกมันว่า Application Managed EntityManager เมื่อเราสร้าง EntityManager ขึ้นมาเราต้องเป็นคนปิด EntityManager ด้วยโดยเราต้องเขียนคำสั่งการ Manage(สร้าง และ ปิด) มันไว้ใน Application ของเรานั้นเองครับ

Appliction Managed PersistenceContext นั้นจะมีขนิดของ PersistenceContext Type เป็น extended เพราะว่าเราสามารถควบคมการเปิด ปิดของ Persistence Context ได้ด้วยตัวเราเอง ดังนั้นมันจึงทำงานข้าม business method หลายๆอันได้

JTA vs RESOURCE_LOCAL



me on google plus+Jirawong Wongdokpuang

Advertisements

Java Virtual Machine Memory Management

ในการจัดการ memory ของ jvm นั้นจะแบ่งส่วนต่างๆ ออกเป็นสามส่วนหลักๆคือ
Young Generation, Old Generation และ Permanent Generation ซึ่งแต่ละส่วนจะมีหน้าที่จัดการกับ memory อย่างชัดเจน

Screen Shot 2556-01-03 at 11.57.08 PM

ภาพนี้เป็นภาพที่สวยที่สุดแล้วจากความพยายามใช้ openoffice ของผม

Continue reading

JSR 330: Dependency Injection for Java Example

JSR 330: Dependency Injection for Java เป็นการทำ DI(Dependency Injection) ใน Java สำหรับ JSR 330 ได้ Specification Leads จาก SpringSource คือ Rod Johnson ซึ่งเป็นคนสร้าง Spring Framework และ Co-Founder ของ SpringSource และ Bob Lee ผู้สร้าง Guice framework และได้รับรางวัล Jolt Awards (Java Collections Framework ของ Joshua Bloch ก็ได้รับรางวัลนี้เช่นเดียวกัน ซึ่ง Joshua Bloch ก็เป็นคนเขียนหนังสือยอดนิยมชื่อ Effective Java เมื่อกล่าวแบบนี้แล้วน่าจะพอคุ้นเคยกันบ้างนะครับ แต่เรื่องนี้ไม่ได้เกี่ยวกับ JSR 330 ที่กำลังพูดถึงอยู่ แค่เล่าให้ฟังเฉยๆ) สำหรับ Example นี้ผมจะแยกออกเป็นสามส่วนคือ DAO , Service และส่วนของ Servlet ซึ่งผมได้ทำการเพิ่ม Dependency ในโปรเจคผมตามนี้ครับ(โปรเจคเป็น maven project นะครับ)

Continue reading

Type Parameter Naming Conventions


เคยสังเกตหรือไม่ว่า API ที่มีการใช้งานแบบ Generic Type นั้นมักใช้ตัวแปรพวก K , V , T อย่างเช่น List<E> อะไรแบบนี้ ถึงแม้ที่จริงแล้วมันจะใส่อะไรก็ได้ แต่ถ้าจะให้ดีความใส่ให้มีความหมาย ซึ่งหากดูตาม Conventions แล้วจะมีดังนี้

E – Element (used extensively by the Java Collections Framework)
K – Key
N – Number
T – Type
V – Value
S,U,V etc. – 2nd, 3rd, 4th types

Ref : Oracle Docs



me on google plus+Jirawong Wongdokpuang

JSR 310: Date and Time API Example

JSR 310: Date and Time API เป็น api ที่เกี่ยวกับ วันและเวลา ซึ่งได้ Stephen Colebourne founded และ leads ของ Joda-Time project Michael Nascimento Santos founded และ leads ของ Genesis project และ Roger Riggs ซึ่งเป็นทึมงานของ Oracle มาเป็น Specification Leads โดยในขณะที่ผมเขียนบทความนี้ JSR 310 อยู่ในสถานะ Active ใน JCP ver. 2.9

JSR 310 นั้นเป็น API ที่มีความใกล้เคียงกับ Joda-Time มาก(ก็ได้ project founder มาเป็น spec leads นี่หน่า) โดย package ของ JSR 310 จะอยู่ใน javax.time เสียส่วนมาก สำหรับคนที่ใช้งาน Joda-time อยู่เป็นนิจอยู่แล้วคงไม่ต้องอะไรมากกับ api ตัวนี้ครับ เพราะต่างกันน้อยมาก เท่าที่เห็นก็น่าจะเป็นพวก enum และ builder pattern ที่ถูกใส่เข้ามาให้ใช้งานง่ายขึ้น

Continue reading

Builder Pattern

Builder Pattern เป็น pattern ที่ใช้สำหรับแก้ปัญหาที่เกิดในลักษณะของ Telescoping Constructor Pattern คือ ต้องการสร้าง class ที่มีความหลากหลายของตัวเลือก และ parameter ของ Constructor หรือ Method มีจำนวนมาก ซึ่งจะทำให้ยากต่อการตีความของ parameter แต่ละตัว ผมขอยก Class ที่ใช้อธิบายในบทความ Telescoping Constructor Pattern มาทำเป็น Builder Pattern เพื่อให้ง่ายต่อการเปรียบเทียบลักษณะของปัญหาและรูปแบบการใช้งาน

public class Vegetable {
	// amount of vitamin in vegetable (mg)
	private final int c;
	private final int a;
	private final int b1;
	private final int b6;
	private final int b12;
	private final int d;

	public static class Builder {

		// require
		private final int c;

		// option
		private int a;
		private int b1;
		private int b6;
		private int b12;
		private int d;

		public Builder(int c) {
			this.c = c;
		}

		public Builder a(int a) {
			this.a = a;
			return this;
		}

		public Builder b1(int b1) {
			this.b1 = b1;
			return this;
		}

		public Builder b6(int b6) {
			this.b6 = b6;
			return this;
		}

		public Builder b12(int b12) {
			this.b12 = b12;
			return this;
		}

		public Builder d(int d) {
			this.d = d;
			return this;
		}

		public Vegetable build() {
			return new Vegetable(this);
		}
	}

	private Vegetable(Builder builder) {
		this.c = builder.c;
		this.a = builder.a;
		this.b1 = builder.b1;
		this.b6 = builder.b6;
		this.b12 = builder.b12;
		this.d = builder.d;
	}

	public static void main(String[] args) {
		Vegetable tomato = new Vegetable.Builder(10).build();
		Vegetable kale = new Vegetable.Builder(5).a(8).b1(1).b6(0).b12(6).d(3).build();
	}
}

จากโค๊ดตัวอย่างผมได้ทำการสร้าง static nested class ไว้ใน class Vegetable ชื่อว่า Builder ซึ่ง class นี้จะทำหน้าที่รวบรวม property ที่เราสนใจ นั้นก็คือ vitamin นั้นเอง และ method สุดท้ายของ class Builder จะเป็นการสร้าง class Vegetable โดยส่วนนี้จะทำงานคู่กับ private constructor ของ Class Vegetable

		//method ในคลาส Builder สำหรับสร้าง SuperClass
		public Vegetable build() {
			return new Vegetable(this);
		}
...
...
...
	//private constructor เพื่อให้ inner class เรียกใช้งาน
	private Vegetable(Builder builder) {
		this.c = builder.c;
		this.a = builder.a;
		this.b1 = builder.b1;
		this.b6 = builder.b6;
		this.b12 = builder.b12;
		this.d = builder.d;
	}

เมื่อเราสร้าง Builder class แล้วประเราสามารถเรียกใช้งานโดยการ new ผ่าน superclass

	public static void main(String[] args) {
		Vegetable tomato = new Vegetable.Builder(10).build();
		Vegetable kale = new Vegetable.Builder(5).a(8).b1(1).b6(0).b12(6).d(3).build();
	}

จะเห็นว่าค่าทุกค่าที่เราใส่เข้าไปเราจะใช้ผ่าน method เฉพาะของมันทำให้เราเข้าใจได้ทันทีว่าเรา set ค่าอะไรไปเท่าไหร่และเมือเรา set ค่าเรียบร้อยแล้วเราก็จะจบด้วย method build เพื่อสร้าง class Vegetable ขึ้นมา

การใช้งาน Builder pattern สามารถนำไปใช้กับ abstract factory pattern ได้ เพื่อสร้างความยีดหยุ่นให้กับคลาสโดยผมจะขอยกตัวอย่างการใช้ abstract factory pattern ร่วมกับ builder pattern ในบทความต่อไปครับ

Ref. Prentice Hall – Effective Java (P.13-16)



me on google plus+Jirawong Wongdokpuang

Java Initializer Block

Initializer Block เป็นการเขียน Block ของโค๊ดขึ้นมาธรรมดาทั่วไป และไม่มี state หรือ behavier ใดๆมานำหน้า แต่หากหากความสามารถนั้นไม่ธรรมดา การสร้าง Initializer Block นั้นจะมีอยู่สองแบบ คือ

Static Initializer Block ซึ่งมีลักษณะการเขียนเป็น

public class SomeClass{
	static{
		//Code
	}
}

static initializer block เป็น initializer block ที่ใช้สำหรับ static context

Initializer Block(ไม่มี static นำหน้า) ซึ่งมีลักษณะการเขียนเป็น

public class SomeClass{
	{
		//Code
	}
}

ความสามารถของ initializer block คือการ initial ค่าต่างๆให้กับ Constructor ได้เพราะว่ามันจะถูกเรียกก่อน Constructor ซึ่งมักนิยมใช้ share การทำงานที่ซ้ำซ้อนเมื่อ Class นั้นมีหลาย Constructor

ตัวอย่างโค๊ดที่แสดงด้านล่างเป็นตัวอย่างในการ initial ค่่าให้กับ Constructor

public class A {

    private static int initialValue;
    private int count;

    public A() {
        System.out.println("Number Of New Class A : " + count);
    }
    
    public A(int plus) {
        System.out.println("Number Of New Class A : " + (count+plus));
    }

    static {
        initialValue = 0;
    }

    {
        count = ++initialValue;
    }

    public int getCount() {
        return count;
    }
}
public class B {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new A();
        A a3 = new A(10);
        A a4 = new A(20);
    }
}

ผลลัพธ์ที่ได้จากการ run Class B คือ

Number Of New Class A : 1
Number Of New Class A : 2
Number Of New Class A : 13
Number Of New Class A : 24


me on google plus+Jirawong Wongdokpuang