หน้าเว็บ

แสดงบทความที่มีป้ายกำกับ JPA(Java Persistence API) แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ JPA(Java Persistence API) แสดงบทความทั้งหมด

วันจันทร์ที่ 21 กรกฎาคม พ.ศ. 2557

แก้ปัญหา GlassFish Application Server โหลด JPA EclipseLink ตัวเก่า


        โดยปกติแล้ว  เวลาเราใช้งาน JPA (EclipseLink) เราไม่จำเป็นต้อง add libraries หรือ dependencies เพิ่มเติมเข้ามาใน project เราก็สามารถใช้งาน jpa ได้ทันที (feature ของ application server : GlassFish) เพราะ jpa มันเป็น spec อยู่แล้ว application server ก็เลยอำนวยความสะดวกตรงนี้ให้เรา

        แต่ถ้าบางครั้งเราต้องการ config JPA เอง หรือต้องการ feature ของ JPA ที่มากกว่าที่ application server เตรียมมาให้  เราต้องทำการบอก application server (GlassFish) ว่าให้มาอ่าน config จากเราไปแทน เช่น ปัจจุบัน  ผมใช้ GlassFish 4.0 ในการพัฒนา project ตัว GlassFish จะมี EclipseLink 2.3.2.X แถมมาให้  แต่ผมต้องการใช้ EclipseLink 2.4.2 (ต้องการใช้ LEFT JOIN)  ซึ่งถ้าเราเขียน JPQL แบบใหม่  แต่ใช้ JPA ตัวเก่า  เราก็จะ run project ไม่ผ่าน

วิธีแก้

วันพุธที่ 30 ตุลาคม พ.ศ. 2556

INNER JOIN jpa spring data

โจทย์ คือหาโรงพยาบาล (Hospital) ภายใต้จังหวัดที่กำหนด
 และต้องเป็นโรงพยาบาลที่อยู่ในโครงการ (InHospital) เท่านั้น
package com.blogspot.na5cent.api.repository;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.blogspot.na5cent.basicmodel.readonly.Hospital;
import com.blogspot.na5cent.basicmodel.readonly.Province;

/**
 *
 * @author redcrow
 */
public interface HospitalRepository extends JpaRepository<Hospital, String>{
    
        @Query("SELECT hp FROM InHospital inHp INNER JOIN inHp.hospital hp WHERE hp.province = ?1")
        public List<Hospital> findByProvince(Province province);
} 
Hospital.java
...
...
...

@Entity
@Table(name = "hospital")
@ReadOnly
public class Hospital implements Serializable {
    @Id
    @Column(nullable = false, length = 5)
    private String hcode;
    @Column(nullable = false, length = 250)
    private String hname;
    @ManyToOne
    @JoinColumn(name = "province_id", nullable = false)
    private Province province;

    ...
    ...
    ...
}
InHospital.java
...
...
...

@Entity
@Table(name = "in_hospital")
public class InHospital implements Serializable {

    @Id
    @Column(name = "hcode", length = 9)
    private String hcode;
    @Version
    private Integer version;
    @OneToOne
    @JoinColumn(name = "hcode", insertable = false, updatable = false)
    private Hospital hospital; 

    ....
    ....
    ....
}

วันจันทร์ที่ 28 ตุลาคม พ.ศ. 2556

spring data jpa repository SQL IN statement

ส่ง List<Type> เข้าไป 
ตรง IN ไม่ต้องมี ( ) ให้ใส่เป็น IN ?1 ได้เลย
package com.blogspot.na5cent.web.repository;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.blogspot.na5cent.api.model.RecordItem;

/**
 *
 * @author redcrow
 */
public interface RecordItemRepository extends JpaRepository<RecordItem, Integer> {

    @Query(value = "SELECT item FROM RecordItem item WHERE item.recoredId IN ?1") //*****
    public List<RecordItem> findInRecordIds(List<Integer> recordIds);
}

วันพุธที่ 2 ตุลาคม พ.ศ. 2556

Lazy load attribute Entity class JPA

Staff.java
...
import javax.persistence.Basic;
...
...
...

@Entity
@Table(name = "Staff")
public class Staff implements Serializable{
    ....
    ....
    ....
    @Lob
    @Basic(fetch = FetchType.LAZY) //****
    private byte[] image;
}

วันอังคารที่ 22 มกราคม พ.ศ. 2556

การสร้าง Composite Key JPA (Object Relational Mapping)

reference key : http://na5cent.blogspot.com/2011/12/keys-database.html

1. สร้าง embeded table ที่จะใช้เป็น composite key
        hash code กับ equal ให้ใช้ attribute ทั้งหมด (3 ตัว)
package com.blogspot.na5cent.model;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;

/**
 *
 * @author Redcrow
 */
@Embeddable //บอกว่าเป็น embeded 
public class DocumentSequencePK implements Serializable {

    @Column(name = "SEQUENCE_NUMBER_MAJOR", nullable = false)
    private Long sequenceNumberMajor;
    @Column(name = "SEQUENCE_NUMBER_MINOR", nullable = false)
    private Integer sequenceNumberMinor;
    @Column(name = "FISCAL_YEAR", nullable = false)
    private Integer fiscalYear;

    public DocumentSequencePK() {
    }

    public DocumentSequencePK(Long sequenceNumberMajor, Integer sequenceNumberMinor, Integer fiscalYear) {
        this.sequenceNumberMajor = sequenceNumberMajor;
        this.sequenceNumberMinor = sequenceNumberMinor;
        this.fiscalYear = fiscalYear;
    }

    public Long getSequenceNumberMajor() {
        return sequenceNumberMajor;
    }

    public Integer getSequenceNumberMinor() {
        return sequenceNumberMinor;
    }

    public Integer getFiscalYear() {
        return fiscalYear;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 41 * hash + (this.sequenceNumberMajor != null ? this.sequenceNumberMajor.hashCode() : 0);
        hash = 41 * hash + (this.sequenceNumberMinor != null ? this.sequenceNumberMinor.hashCode() : 0);
        hash = 41 * hash + (this.fiscalYear != null ? this.fiscalYear.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final DocumentSequencePK other = (DocumentSequencePK) obj;
        if (this.sequenceNumberMajor != other.sequenceNumberMajor && (this.sequenceNumberMajor == null || !this.sequenceNumberMajor.equals(other.sequenceNumberMajor))) {
            return false;
        }
        if (this.sequenceNumberMinor != other.sequenceNumberMinor && (this.sequenceNumberMinor == null || !this.sequenceNumberMinor.equals(other.sequenceNumberMinor))) {
            return false;
        }
        if (this.fiscalYear != other.fiscalYear && (this.fiscalYear == null || !this.fiscalYear.equals(other.fiscalYear))) {
            return false;
        }
        return true;
    }
}

วันจันทร์ที่ 21 มกราคม พ.ศ. 2556

Multiple Order By PageRequest Spring Data

SQL
...
SELECT FISCALYEAR, SEQUENCENUMBER 
FROM DOCUMENT_SEQUENCE 
ORDER BY FISCALYEAR DESC, SEQUENCENUMBER DESC
...
repository
...
...
public interface DocumentSequenceRepo extends JpaRepository<DocumentSequence, DocumentSequencePK> {

    @Query("SELECT ds.id FROM DocumentSequence ds")
    public Page<DocumentSequencePK> findLatestSequence(Pageable page);
   
}

service
...
...

@Override
public DocumentSequencePK findLatestSequence() {
    String[] sortBy = {"id.fiscalYear", "id.sequenceNumber"}; //**************
    PageRequest pageRequest = new PageRequest(0, 1, Sort.Direction.DESC, sortBy);

    Page<DocumentSequencePK> pk = documentSequenceRepository.findLatestSequence(pageRequest);
    if (pk.getTotalElements() == 0) {
        return new DocumentSequencePK(1L, DateUtils.getFiscalYear(new Date()));
    } else {
        return pk.getContent().get(0);
    }
}
...
...

วันอาทิตย์ที่ 13 มกราคม พ.ศ. 2556

การ config database ให้สามารถใช้งานร่วมกับ web application ที่เราสร้างขึ้น : java, jpa, spring



        การ config database จะมีอยู่ 2 แบบ  น่ะครับ  คือ
1. แบบ Resources Local  คือ เราเป็นคน config database ไว้ใน web application ของเราเลย  ข้อดีคือ  ไม่ต้อง config อะไรเพิ่มเติม เมื่อเอาไป deploy แต่มีข้อเสียคือ  เวลาเปลียน database ที เราก็ต้องมาแก้ code application ของเราใหม่ตลอด 

2. แบบ JTA (Java Transaction API) คือวิธีนี้  เราจะ config database ไว้ที่ application server โดยใช้ JNDI แล้วให้ web application ของเรา point ไปที่ resources นั้นแทน  ข้อดีคือจัดการง่าย  เวลาที่ต้องการเปลี่ยนแปลง database ก็ไม่ต้องมาแก้ไข  code  application ของเรา ใหม่ การ  maintenance  และ management  อะไรต่างๆ ง่ายกว่า  และที่สำคัญคือรองรับ XA transaction หรือ  Global transaction ที่สามารถทำ transaction แบบ multiple data-store ได้อีกด้วย  แต่ข้อเสียคือ  ต้อง config ที่ application server เพิ่มเติม  ไม่เสร็จสับในทีเดียวเหมือน  resource   local


การ config จะต้องเป็นแบบใดแบบหนึ่งเท่านั้น
ปกติผมจะใช้แบบที่ 2 (JTA) เพราะว่ามัน management ได้ง่ายกว่า

ทั้ง 2 อย่างนี้  มีส่วนที่ต่างกันอยู่ 2 ไฟล์ครับ คือ
1. applicationContext-database*.xml
2. persistence*.xml

ซึ่งจะ config ไม่เหมือนกัน

วันเสาร์ที่ 12 มกราคม พ.ศ. 2556

รู้จักกับ ORM (Object Relational Mapping)



ORM (Object Relational Mapping) คืออะไร?

        ORM หรือ Object Relational Mapping  ถ้าจะว่าไปมันก็คือการเขียนโปรแกรมอย่างหนึ่ง ไม่ว่าจะเขียนด้วยภาษาโปรแกรมมิ่งอะไรก็ตาม  จุดประสงค์ก็เพื่อแปลงจาก Object ไปเป็น Database หรือแปลงจาก Database กลับมาเป็น Object ครับ   concept มีแค่นี้   

        เราไม่จำเป็นต้องยุ่งในส่วนของ SQL (SELECT, INSERT, UPDATE, DELETE) เลย  แต่เราจะใช้ framework มาช่วยจัดการแปลงจากภาษาโปรแกรมมิ่งที่เราเขียน ไปเป็น SQL หรือ database ให้เราแทน  

ขอยกตัวอย่างเช่น ภาษา java  ซึ่งก็มี framework ช่วยอยู่หลายตัว  แต่ที่ดังๆ ก็จะมี EclipseLink และ Hibernate   เวลาที่เราต้องการจะสร้าง database table ขึ้นมา table นึง  เราไม่จำเป็นต้องเขียน SQL เพื่อ create table ขึ้นมาเลย  เราแค่เขียน  java class ขึ้นมา  ซึ่ง java class นี้จะถูกเรียกว่า Entity Class จากนั้นก็กำหนด attribute ต่างๆ  ตามที่ต้องการลงไป  attribute นี้เราอาจจะมองว่ามันคือ column ของ table ก็ได้  ทีนี้ framework  มันก็จะเอา  entity class ที่เราเขียนไว้ไปแปลงเป็น table ให้เราเองครับ  
        การ map relation ต่างๆ เช่น One to One, One to Many หรือ Many to May  เราอยากได้แบบไหน  เราก็เขียนลงไปใน  entity class นั้น  framework มันก็จะเอาไป map ให้เราเอง  มันจะสร้าง foreign key, primary key  ซึ่งเป็นความสัมพันธ์ต่างๆ ของ table ให้เองโดยอัตโนมัติ 

        การอ่านค่าจาก table ขึ้นมาใช้   มันก็จะแปลงจากข้อมูลที่อยู่ในรูปของ row ไปเป็น object ของ row นั้นให้  ซึ่งไม่เหมือนกับการเขียน code แบบเดิมๆ  ที่ต้องเขียน code เพื่ออ่านค่ามาจาก database  และก็ค่อยจับค่าที่อ่านมาได้นั้นยัดเข้าไปใน object class เอง  ซึ่งมันก็ค่อนข้างลำบากอยู่เหมือนกันครับ  ถ้าระบบเราเป็นระบบที่ใหญ่มากๆ  การดูแลรักษา  หรือการแก้ไข code ก็จะเกิดความยุ่งยากขึ้นได้  เพราะ code ที่เราเขียนมันผูกกันไปมาเต็มไปหมด  ยิ่งถ้าแก้ attribute ใน table หรือเปลี่ยนแปลงความสัมพันธ์ของ table ที  ก็ต้องมาตามแก้  Class  ที่อ้างไปถึง table นั้นๆ อีก เรียกว่าเหนื่อยกันหลายต่อเลยครับ

        พอเราหันมาใช้ ORM  มันก็จะช่วยให้งานเราสบายขึ้นเยอะ  เวลาแก้ attribute หรือความสัมพันธ์ใน Entity Class  ตัว attribute หรือความสัมพันธ์ของ table ก็จะเปลี่ยนแปลงตามไปด้วย   เราอาจจะมองว่า entity class กับ database table มันคือตัวเดียวกันก็ได้ครับ  เพราะ framework  มันจะจัดการทำ mapping ให้เรา  สบายแมวเลยทีนี้  ^___________^

ลองดูตัวอย่างนี้ดูครับ  เผื่อจะเข้าใจ

วันอังคารที่ 8 มกราคม พ.ศ. 2556

การสร้างคำสั่ง Query(JPQL) และการเรียกใช้งานผ่าน Service : java

JPQL คืออะไร?
        JPQL ย่อมาจาก Java Persistence Query Language  มันก็เหมือนกับการเขียนคำสั่ง Query ข้อมูล แบบ SQL ทั่วๆไปนั่นเองครับ  เพียงแต่ว่า  มันจะเป็นการเขียน Query ในลักษณะของการ Query ข้อมูลจาก Entity Class (http://na5cent.blogspot.com/2013/01/entity-class-map-entity-relationship.html) แทน  ค่าที่ได้จะเป็น Object เสมอ ตัวอย่างประมาณนี้ครับ

วันจันทร์ที่ 7 มกราคม พ.ศ. 2556

การสร้าง Entity class และเรียนรู้การ Map Entity Relationship : java

Entity class คืออะไร?

        ถ้าจะว่าไปมันก็คือการ Map จาก Java Class => Database Table นั่นเองครับ  คือเราไม่จำเป็นต้องเขียนคำสั่ง SQL เพื่อ Create Table เอง  เราแค่เขียน java class ขึ้นมา  จากนั้น framework มันก็จะจัดการแปลงไปเป็น  table ให้เราเองโดยอัตโนมัติ  เวลาที่เราดึงค่ามาจาก database มันก็จะแปลงจาก row มาเป็น object ให้เราเอง  อาจจะเรียกว่าการทำ ORM หรือ Object Relational Mapping  นั่นเองครับ  เรามาดูวิธีการสร้างกันเลยดีกว่า


หลักการสร้าง Entity Class (EclipseLink)
  1. เป็น java class ตั้งชื่อว่าอะไรก็ได้ (ให้สื่อกับความหมายนั้นๆ)
  2. implements Serializable
  3. มี annotation @Entiry อยู่บน class
  4. Entity Class ต้องมี default constructor ที่ไม่มี parameter เท่านั้น  เช่น public Category(){ }
  5. ในกรณีที่ต้องการกำหนดค่าบางอย่างของ Table  ให้ใช้ annotation @Table  เช่นการกำหนดชื่อให้ table จะใช้ attribute name  แต่ถ้าไม่ได้กำหนดชื่อ  default table name จะเป็นชื่อของ entity class นั้นๆ การตั้งชื่อ table ให้ระวังเรื่อง reserve word ของ database แต่ละเจ้า
  6. กำหนด attribute
  7. จะต้องมี attribute อย่างน้อย 1 attribute ที่มี annotation @Id เพื่อบอกว่าเป็น primary key
  8. มี method getter และ setter เพื่อ get และ set ค่าให้กับแต่ละ attribute
  9. ในการกำหนดค่าแต่ละ attribute หรือแต่ละ column ให้ใช้ annotation @Colum อยู่บน attribute นั้นๆ
  10. การ map relationshipให้สร้าง attribute ที่มี data type เป็น Entity Class ที่ต้องการ map ด้วย   จากนั้นก็ใส่ annotation Mapping ต่างๆ  ไว้บน attribute นั้นๆ เช่น
    1. @OneToOne
    2. @OneToMany
    3. @ManyToOne
    4. @ManyToMany
หลักการคร่าวๆ มีประมาณนี้ครับ  ต่อไปลองมาสร้างดูครับ

วันจันทร์ที่ 26 พฤศจิกายน พ.ศ. 2555

Map [Many to One and One to Many] : JPA

Table UserForum
...
...
...

@Table(name = "USER_FORUM")
@Entity
public class UserForum implements Serializable {

    @Id
    @TableGenerator(name = "UserForum_GEN", table = "WEBBOARD_SEQ", pkColumnName = "NAME", valueColumnName = "VALUE", pkColumnValue = "USER_FORUM")
    @GeneratedValue(generator = "UserForum_GEN", strategy = GenerationType.TABLE)
    @Column(name = "USER_FORUM_ID")
    private Integer id;
    @Version
    private Integer version;
    //information
    private String userName;
    private String password;
    private String fullName;
    private String email;
    private String image;
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    private Date joinDate;
    //join
    @ManyToMany
    @JoinTable(name = "ANSWER",
    joinColumns = {
        @JoinColumn(name = "USER_FORUM", referencedColumnName = "USER_FORUM_ID")},
    inverseJoinColumns = {
        @JoinColumn(name = "CATEGORY", referencedColumnName = "CATEGORY_ID")})
    private List<Category> categories;
    @OneToMany(mappedBy = "owner")
    private List<Post> posts;
    @OneToMany(mappedBy = "owner")
    private List<Comment> comments;

    ...
    ...
    ...
}

Sequence auto generate by table generator : JPA

..
..
..

@Table(name="COMMENT")
@Entity
public class Comment implements Serializable{
    @Id
    @TableGenerator(name = "Comment_GEN", table = "WEBBOARD_SEQ", pkColumnName = "NAME", valueColumnName = "VALUE", pkColumnValue = "COMMENT")
    @GeneratedValue(generator = "Comment_GEN", strategy = GenerationType.TABLE)
    @Column(name = "COMMENT_ID")
    private Integer id;
    @Version
    private Integer version;

    //information
    ...
    ...
    ...
}

วันจันทร์ที่ 24 กันยายน พ.ศ. 2555

Sub Query Qriteria JPA Eclipse Link + Spring Data : Java

เข้าใจ Dynamic Query Qriteria JPA Eclipse Link + Spring Data : Java : http://na5cent.blogspot.com/2012/09/dynamic-query-qriteria-jpa-eclipse-link.html

JPA Repositories
SELECT s 
FROM Staff s 
WHERE s.staffId NOT IN(
    SELECT u.staffId 
    FROM User u 
    WHERE u.disabled = false
)
Specification

วันอาทิตย์ที่ 16 กันยายน พ.ศ. 2555

เข้าใจ Dynamic Query Criteria JPA Eclipse Link + Spring Data : Java

อะไรคือ Dynamic Query ?
        จากที่ผ่านมา http://na5cent.blogspot.com/2013/01/queryjpql-service-java.html  การสร้างคำสั่ง Query ของเรา จะเป็นการ Fixed code ไว้  อยาก select อะไร select กี่ field เราก็เขียน select field นั้นลงไปเลย  แต่ถ้าเราเจอปัญหาในลักษณะที่ว่า Dynamic เช่น User ต้องการ select field อะไรก็ได้ แล้วแต่เขาจะเลือก  คำสั่ง SQL นั้นอาจประกอบไปด้วย 1 field, 2 field, 3 field  ... ถ้าเจอแบบนี้  เราจะทำยังไง  จะเขียน SQL ของทั้งหมดที่เป็นไปได้เหรอ  ใครทำแบบนั้น  ก็ทำไปเถอะครับ  ผมคนนึงล่ะที่ไม่เอาด้วย  คงไม่ต้องไปทำมาหากินอย่างอื่นแล้ว  แค่นั่งเขียน code ทุกความเป็นไปได้ทั้งหมด  ตัวอย่างเช่น ถ้ามีซัก 5 field มันก็คงจะประมาณนี้มั้งครับ  ที่ต้องเขียน
  1. EmpID
  2. EmpID + FirstName
  3. EmpID+LastName
  4. EmpID+DepID
  5. EmpID+Position
  6. EmpID+FirstName+LastName
  7. EmpID+FirstName+DepID
  8. EmpID+FirsttName+Position
  9. EmpID+LastName+DepID
  10. EmpID+LastName+Position
  11. EmpID+DepID+Position
  12. EmpID +FirstName+LastName+DepID+Position
  13. ...
        หรืออาจมีอีก อันนี้ผมก็ไม่ได้ไล่ทั้งหมดน่ะครับ  ขี้เกียจไล่  เอาเป็นว่ามันก็จะเป็นแบบนี้แหล่ะ  ต้องมาเขียนไล่เองทั้งหมด  แล้วถ้าเขามีการแก้ไข database เป็น 6 7 หรือ 8 field ล่ะ  ตายเลย!!!

        เรามาเขียน dynamic query กันดีกว่า  ช่วยให้งานเราสบายขึ้นครับ  แค่อาจต้องเรียนรู้เพิ่มเติมอีกนิดหน่อย
เรามาเริ่มกันเลยดีกว่าครับ

วันศุกร์ที่ 14 กันยายน พ.ศ. 2555

Join entity many to many jpa : java

Services Interface
package com.blogspot.na5cent.services;

import java.util.List;
import com.blogspot.na5cent.model.Project;
import com.blogspot.na5cent.model.User;

public interface UserService{
    public List<User> findUserByProject(Project project);
    
    ...
    ...
}
Service Implementation
package com.blogspot.na5cent.services.impl;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import com.blogspot.na5cent.repositories.UserRepositories;
import com.blogspot.na5cent.services.UserService;
import com.blogspot.na5cent.model.Project;
import com.blogspot.na5cent.model.User;
...
...

@Service
@Transactional(propagation = Propagation.REQUIRED)
public Class UserServiceImpl implements UserService{
    @Autowired
    private UserRepositories userRepo;

    private List<User> findUserByProject(Project project){
        return userRepo.findByProject(project);
    }

    ...
    ...
}
Repositories
package com.blogspot.na5cent.repositories;

import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import com.blogspot.na5cent.model.Project;
import com.blogspot.na5cent.model.User;
...
...
public interface UserRepositories extends JpaRepository<User, Integer>, JpaSpecificationExecutor {
    @Query("SELECT u FROM Project p JOIN p.users u WHERE p = ?1")
    public List<User> findByProject(Project project);

    ...
    ...
}

วันอังคารที่ 4 กันยายน พ.ศ. 2555

use multiple base package repositories : java

        ในการใช้งาน JPA จะต้องมีการกำหนด base package repositories  ไว้ในไฟล์ applicationContext.xml (โดย default) ว่า model หรือ entity ของเราถูกเก็บไว้ที่ไหน  เพื่อที่จะได้นำไปสร้างเป็น  database table ในภายหลัง
        ทีนี้ ปัญหาที่ผมเจอมีอยู่ว่า  ผมเก็บ repositories ไว้หลายที่  วิธีการเก็บหลายที่ก็คือ  ให้เราทำการแยก tag  <jpa:repositories />  ของแต่ละที่ออกจากกันเลยครับ ดังนี้
    
...
...
<jpa:repositories base-package="com.na5cent.blogspot.base.repositories"/>
<jpa:repositories base-package="com.na5cent.blogspot.senddata.repositories" />
...
...
        การใช้ tag เดียว แล้วเขียนต่อกันดังต่อไปนี้ไม่ถูกต้องน่ะครับ โปรแกรมจะ run ไม่ผ่าน และจะไม่สามารถสร้าง repositories ได้
...
...
<jpa:repositories base-package="com.na5cent.blogspot.base.repositories, com.na5cent.blogspot.senddata.repositories"/>
...
...