मुझे अपनी दृढ़ता परत में कई सहयोगियों के साथ समस्या है। मेरा परिदृश्य निम्न है:हाइबरनेट कई से कई एसोसिएशन: बाएं हाथ की ओर संग्रह में तत्व होते हैं, लेकिन दाएं हाथ की ओर संग्रह खाली है
उपयोगकर्ता के पास कई भूमिकाएं हो सकती हैं और भूमिका में कई उपयोगकर्ता संलग्न हो सकते हैं। परीक्षणों के दौरान मुझे एक अजीब व्यवहार का सामना करना पड़ा। मैंने भूमिका वस्तु और कई उपयोगकर्ता वस्तुओं का निर्माण किया। भूमिका प्रत्येक उपयोगकर्ता को सेट की गई थी। इसके बाद उपयोगकर्ताओं को डीएओ का उपयोग करके बचाया गया। फिर उपयोगकर्ता में से एक को यह जांचने के लिए लोड किया जाता है कि उसे उपयोगकर्ता ऑब्जेक्ट को सहेजने से पहले उसे पास किया गया था या नहीं। उपयोगकर्ता पर getRoles()
पर कॉल करना दर्शाता है कि भूमिका सही ढंग से सेट की गई थी।
यह जांचने के लिए कि क्या विपरीत दिशा भी काम करती है, भूमिका भूमिका डीएओ का उपयोग करके डेटाबेस से लोड हो जाती है। लेकिन रोल ऑब्जेक्ट पर getUsers()
पर कॉल करना केवल एक खाली सेट देता है, हालांकि इसमें इस भूमिका के साथ सभी उपयोगकर्ता शामिल होना चाहिए।
मैंने डेटाबेस तालिका को दो बार चेक किया लेकिन सबकुछ ठीक लगता है। उपयोगकर्ता, भूमिका और user_role तालिका सभी ठीक से भर गए थे।
तो भूमिका वस्तु में कोई उपयोगकर्ता क्यों नहीं है?
मैं निम्नलिखित कक्षाओं के साथ हाइबरनेट और वसंत का उपयोग कर रहा हूं।
उपयोगकर्ता वर्ग
@Entity
@Table
public class User extends BusinessObject {
...
// Option 1
@ManyToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
targetEntity=Role.class)
@JoinTable(name= "user_role",
joinColumns = {@JoinColumn(name="user_id")},
inverseJoinColumns = {@JoinColumn(name="role_id")})
// Option 2
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name= "user_role",
joinColumns = {@JoinColumn(name="user_id")},
inverseJoinColumns = {@JoinColumn(name="role_id")})
private Set<Role> roles = new HashSet<Role>();
...
}
भूमिका वर्ग
@Entity
@Table
public class Role extends BusinessObject {
...
// Option 1
@ManyToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,
mappedBy= "roles",
targetEntity = User.class)
// Option 2
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name= "user_role",
joinColumns = {@JoinColumn(name="role_id")},
inverseJoinColumns = {@JoinColumn(name="user_id")})
private Set<User> users = new HashSet<User>();
...
}
मैं एक JUnit परीक्षण वर्ग में निम्नलिखित कोड का उपयोग कर रहा परीक्षण करने के लिए।
@Test
public void test(){
Transaction trans = sessionFactory.getCurrentSession().beginTransaction();
Role userAdminRole = new Role();
userAdminRole.setName(RoleName.USER_ADMIN);
Role userRole = new Role();
userRole.setName(RoleName.USER);
User user1 = new User();
user1.setEmail("[email protected]");
user1.getRoles().add(userAdminRole);
user1.getRoles().add(userRole);
userDao.save(user1);
User user2 = new User();
user2.setEmail("[email protected]");
user2.getRoles().add(role);
userDao.save(user2);
User user3 = new User();
user3.setEmail("[email protected]");
user3.getRoles().add(role);
userDao.save(user3);
trans.commit();
User loadedUser = userDao.load(user1.getId());
// Tests passes
Assert.assertNotNull(loadedUser);
Assert.assertEquals(user1, loadedUser);
Set<Role> roles = loadedUser.getRoles();
// Tests passes
Assert.assertEquals(2, roles.size());
Role loadedUserAdminRole = roleDao.findByName(RoleName.USER_ADMIN);
Set<User> users = loadedUserAdminRole.getUsers();
// Test fails: Count is 0 instead of 3 !!!!!!!
Assert.assertEquals(3, users.size());
}
अद्यतन
माफ करना, मैं एक बात उल्लेख करना भूल गया। जब मैंने कोड का परीक्षण किया तो मैंने निश्चित रूप से कई वर्ग फ़ाइल में कई बार कई एसोसिएशन को चिह्नित नहीं किया। इसके बजाय मैंने प्रत्येक वर्ग फ़ाइल में विकल्प 1 या विकल्प 2 का उपयोग किया था।
आप कहां शुरू कर रहे हैं और सत्र समाप्त कर रहे हैं (या 'जेपीए में EntityManager')? मुझे संदेह है कि अगर आप 'सेव' के बाद एक सत्र बंद करते हैं और 'लोड' से पहले एक नया शुरू करते हैं, तो चीजें काम करती हैं, क्योंकि यह सत्र कैश की बजाय डेटाबेस से ऑब्जेक्ट खींचती है। –
सत्र पूरी परीक्षा विधि के दौरान खोला गया है। कॉलिंग getSession() को डीएओ की विधि में से एक में हमेशा एक ही सत्र ऑब्जेक्ट देता है जब तक कि उन्हें एक परीक्षण विधि में बुलाया जाता है। – Flo