2015-03-23 7 views
5

हाइबरनेट दस्तावेज की performance section में कहा कि:हाइबरनेट में द्वितीय स्तर के कैश को पेश करके एन + 1 समस्या का समाधान कैसे किया जा सकता है?

एक एन 1 चयन के साथ समस्याओं के लिए पूरी तरह से अलग दृष्टिकोण दूसरे स्तर कैश का प्रयोग है।

मुझे समझ में नहीं आता कि यह समस्या का समाधान कैसे कर सकता है। असली दुनिया का उदाहरण और स्पष्टीकरण क्या हो सकता है?

उत्तर

2

यह आसान है। मान लीजिए कि आप निम्नलिखित डोमेन मॉडल करते हैं:

@Entity(name = "Post") 
public class Post { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "post") 
    private List<Comment> comments = new ArrayList<>(); 

    public String getName() { 
     return name; 
    } 

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

    public List<Comment> getComments() { 
     return comments; 
    } 

    public void addComment(Comment comment) { 
     comments.add(comment); 
     comment.setPost(this); 
    } 
} 

@Entity(name = "Comment") 
public class Comment { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @ManyToOne 
    private Post post; 

    public Comment() { 
    } 

    public Comment(String review) { 
     this.review = review; 
    } 

    private String review; 

    public Long getId() { 
     return id; 
    } 

    public Post getPost() { 
     return post; 
    } 

    public void setPost(Post post) { 
     this.post = post; 
    } 

    public void setReview(String review) { 
     this.review = review; 
    } 
} 

आप निम्नलिखित HQL क्वेरी चलाते हैं: प्रत्येक के लिए फिर

List<Comment> comments = session.createQuery(
    "select c from Comment c ").list(); 
for(Comment comment : comments) { 
    Post post = comment.getPost(); 
} 

टिप्पणी आप प्राप्त करने में कठिनाई जुड़े टिप्पणी पोस्ट के लिए एक अतिरिक्त क्वेरी चलाने के लिए होगा ।

आप 2 स्तर कैशिंग सक्षम करते हैं:

@Entity(name = "Post") 
@Cacheable 
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class Post { 
    ... 
} 

तो पहले हाइबरनेट इकाई लोड करने में 2 स्तर कैश करने के लिए चला जाता है और वहाँ कोई कैश प्रविष्टि पाया है कि अगर केवल डेटाबेस पूरी करता है।

एक अधिक आसान समाधान है बस fetch all required data at query-time:

List<Comment> comments = session.createQuery(
    "select c from Comment c fetch c.post ").list(); 

इस तरह आप एन 1 क्वेरी समस्या आने पर नहीं होगा, और आप या तो एक 2 स्तर कैश की जरूरत नहीं होगी। Like any caching solution, दूसरा स्तर कैश असंगतता के लिए प्रवण होता है जब डेटाबेस को हाइबरनेट एपीआई के बाहर अपडेट किया जाता है।

संबंधित मुद्दे