2012-04-22 27 views
7

Oldukça standart bir senaryoya sahibim. Bu sayede, PK kullanıcısı user_id olan bir Kullanıcı Tablosuna ve PK olarak role_id rolüne sahip bir Roles tablosuna sahibim. İki tablo bir çok ilaca ilişkindir (örn. Kullanıcılar birçok role sahip olabilir ve birçok kullanıcıya bir rol uygulanabilir) ve daha sonra kullanici_has_roles adında bir birleştirme tablom var. Users_has_roles'daki yalnızca iki sütun user_user_id ve roles_role_id'dir.JPA, birçok kullanıcı için birçok

Öğe sınıflarını oluşturdum (aşağıya bakın) ve kullanıcılara ve rol tablolarına veriyi kalıcı olarak sormam sorunum var ancak kullanıcılara tabloya katılma konusunda herhangi bir sorun yaşamaya devam edemiyorum, bu nedenle şu anda kullanıcılardan hiçbirine rol atamadım . Çıldırmadan önce, birileri beni sefaletimin dışına çekti ve kullanıcılara rolleri olan bir user_user_id kullanıcısı ile ilgili bir roles_role_id ekleyerek users_has_roles tablosuna nasıl katılacağımı gösterebilir mi?

Benim Users.java varlık sınıfı:

@Entity 
@Table(name = "users") 
@XmlRootElement 
@NamedQueries({ 
@NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"), 
@NamedQuery(name = "Users.findByUserId", query = "SELECT u FROM Users u WHERE u.userId = :userId"), 
@NamedQuery(name = "Users.findByUsername", query = "SELECT u FROM Users u WHERE u.username = :username"), 
@NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password")}) 
public class Users implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@Basic(optional = false) 
@NotNull 
@Size(min = 1, max = 60) 
@Column(name = "user_id") 
private String userId; 
@Basic(optional = false) 
@NotNull 
@Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email") 
@Size(min = 1, max = 45) 
@Column(name = "username") 
private String username; 
@Basic(optional = false) 
@NotNull 
@Size(min = 1, max = 120) 
@Column(name = "password") 
private String password; 
@JoinTable(name = "users_has_roles", joinColumns = { 
    @JoinColumn(name = "users_user_id", referencedColumnName = "user_id")}, inverseJoinColumns = { 
    @JoinColumn(name = "roles_role_id", referencedColumnName = "role_id")}) 
@ManyToMany 
private Collection<Roles> rolesCollection; 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "usersUserId") 
private Collection<UserAccount> userAccountCollection; 
@OneToMany(cascade = CascadeType.ALL, mappedBy = "usersUserId") 
private Collection<UserDetails> userDetailsCollection; 

... 

All the getter and setter methods etc. 

Benim Roles.java varlık sınıfı:

@Entity 
@Table(name = "roles") 
@XmlRootElement 
@NamedQueries({ 
@NamedQuery(name = "Roles.findAll", query = "SELECT r FROM Roles r"), 
@NamedQuery(name = "Roles.findByRoleId", query = "SELECT r FROM Roles r WHERE r.roleId = :roleId"), 
@NamedQuery(name = "Roles.findByRoleName", query = "SELECT r FROM Roles r WHERE r.roleName = :roleName"), 
@NamedQuery(name = "Roles.findByRolePermission", query = "SELECT r FROM Roles r WHERE r.rolePermission = :rolePermission"), 
@NamedQuery(name = "Roles.findByRoleDescription", query = "SELECT r FROM Roles r WHERE r.roleDescription = :roleDescription")}) 
public class Roles implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@Basic(optional = false) 
@NotNull 
@Size(min = 1, max = 60) 
@Column(name = "role_id") 
private String roleId; 
@Basic(optional = false) 
@NotNull 
@Size(min = 1, max = 45) 
@Column(name = "role_name") 
private String roleName; 
@Basic(optional = false) 
@NotNull 
@Size(min = 1, max = 45) 
@Column(name = "role_permission") 
private String rolePermission; 
@Size(max = 45) 
@Column(name = "role_description") 
private String roleDescription; 
@ManyToMany(mappedBy = "rolesCollection") 
private Collection<Users> usersCollection; 

... 

All the getter and setter methods etc. 

Teşekkür

---- GÜNCELLEME ----

// New Users 
Users currentUser = new Users(); 
currentUser.setUserId(userId); 
currentUser.setUsername(email); 
currentUser.setPassword(password); 
getUsersFacade().create(currentUser); 

cevap

6

Örneğiniz iyi çalışıyor (EclipseLink 2.3, MySQL). Muhtemelen sorun, göstermediğiniz kodun bir parçasıdır. Örneğin, rollerCollection öğesine öğe eklerken. Tipik hata, örneğin sadece sahip olmayan tarafa eleman eklemek içindir.

Kalıcı olarak, veritabanında da bellek içi nesne grafiğini korumak için, sahip olma ilişkisini (mappedBy olmadan) tutmanız gerekir, her zaman ilişkinin her iki tarafını da değiştirmeniz gerekir.

aşağıdaki ile denedim: cevap beni lider için Mikko sayesinde kapalı

// method to add element to rolesCollection 
    public void addRoles(Roles r) { 
     rolesCollection.add(r); 
    } 

    //first created new instances of Users and Roles 
    // then: 
    tx.begin(); 
    users.addRoles(r); 
    //it is not needed for persisting, but here you can also 
    //add user to roles. 
    em.persist(users); 
    em.persist(r); 
    tx.commit(); 
+1

Merhaba Mikko, Ben hala şaşkın! Yukarıdaki kodun nasıl çalıştığını anlamıyorum.İlişkinin her iki tarafını da değiştirmem gerekirse, hem rollere hem de KullanıcıKoleksiyonuna rol eklemem gerekir mi? Görünüşe göre sadece rollere ekleniyorsunuz. Ayrıca ilgili koleksiyonlara eklediklerimi de karıştırdım. RollsCollection hem bir user_user_id hem de bir roles_role_id gerektirir mi? – tarka

+0

Sorun şudur: veritabanına kalıcı hale getirilmesi, asgari gerekliliklerin sahip olunan tarafın değiştirilmesidir (mappedBy olmadan). Kötü nokta, mappedBy ile koleksiyonun senkronize olmamasıdır. Bu yüzden, her iki tarafı da değiştirmek daha iyidir, bu da hem rollere hem de rollerin Toplama'ya rol eklemesi anlamına gelir. –

+0

Tamam o zaman en iyi uygulama, her iki Koleksiyona da öğe eklemektir ... ancak her Koleksiyona ne ekleyebilirim? her ikisine de bir user_id ve bir role_id ekliyor muyum? – tarka

8

Tamam ilk. Ben sadece içinde bulunduğum pozisyonda olabilecek herkese doğrudan yardımcı olabilecek bir cevap göndermek istedim. Ayrıca teknik olarak doğru olmayabilir bu yüzden bu bir Eureka anı dayanmaktadır, ancak ben bunu görüyorum.

Karşılaştığım en büyük sorun, MySQL'de köprüleme tablosunu tek bir tablo olarak görebildiğimdi! (Üzgünüm, EER diyagramımın bir resmini yayınlayamıyorum ama şu anda yeterli ayrıcalığa sahip değilim) Bu yüzden Java'nın köprüleme tablosunu bir tablo olarak göreceğini farz ettim! Peki öyle değil. Bu köprüleme tablosu, Java'da geleneksel bir tablo olarak gerçekten mevcut değildir, aslında onunla ilişkilendirdiğiniz karşıt tablo toplama türüyle temsil edilir.

Bunu benim için görmenin en kolay yolu köprüleme tablosunu tamamen unutmak ve iki 'gerçek' tabloya odaklanmak ve verileri bunlarla ilişkilendirmektir. Aşağıdaki kod, sadece rol_id'yi ayarlıyorum, ancak yalnızca amacımı göstermek için en iyi uygulama DEĞİLDİR.

List<Roles> userRoleList = new ArrayList<Roles>(); 

Users currentUser = new Users(); 
currentUser.setUserId(userId); 
currentUser.setUsername(email); 
currentUser.setPassword(password); 

Roles userRole = new Roles(); 
userRole.setRoleId("2"); 

userRoleList.add(userRole); 
currentUser.setRolesCollection(userRoleList); 

getUsersFacade().create(currentUser); 

Birçok ilişkide zorluk çeken herkese yardım etmesini umuyorum.

(NB. Bunun yerine kolaylığı için bir Koleksiyonu Listesini kullanımı için asıl soru kodunu kaydetmiştiniz ama sadece yanı ihtiyaçlarınıza uygun başka türü kullanabilirsiniz.)