Diğer hevesli koleksiyonları içeren varlıkların hevesle toplanmasını sağlayın

Varlık ve dizeler arasındaki M: N ilişkisine takıldım. Bir kullanıcının birden fazla rolü olabilir ve her rol birden fazla kullanıcıya atanabilir. Rol sadece bir dizedir. Roller iki sütun içeren tabloda bulunur: roleId ve roleName .

İki varlık oluşturdum ama kesinlikle işe yaramayacağım. İlk varlık kullanıcıdır:

@Entity
@Table(name="appUsers")
public class UserEntity {
    @Id
    private String login;
    private String password;
    @OneToMany(fetch=FetchType.EAGER,mappedBy="user") //we always need to load user's roles
    private Collection roles;
    @Transient
    private Collection roleNames;

    public String getLogin() {
        return login;
    }

    public String getPassword() {
        return password;
    }

    @PostLoad
    void prepareRoleNames() {
        roleNames = new HashSet(roles.size());
        for (UsersToRoles mapping : roles)
            roleNames.add(mapping.getNameOfRole());
    }

    public Collection getRoles() {
        return roleNames;
    }
}

İkincisi, bağlantı tablosuyla ilişkili varlıktır:

@Entity
@IdClass(UsersToRolesId.class)
public class UsersToRoles {
    @Id
    @SuppressWarnings("unused")
    @Column(name="login")
    private String login;
    @Id
    @SuppressWarnings("unused")
    @Column(name="roleId")
    private int roleId;
    @ElementCollection(fetch=FetchType.EAGER)
    @CollectionTable(name="userRoles", joinColumns={@JoinColumn(name="roleId")})
    private List roleName;
    @ManyToOne
    @JoinColumn(name="login")
    @SuppressWarnings("unused")
    private UserEntity user;

    public String getNameOfRole() {
        if (roleName.isEmpty())
            throw new CommonError("Role name for roleId=" + roleId, AppErrors.ACCESSOR_UNAVAILABLE);
        return roleName.get(0);
    }
}

class UsersToRolesId {
    private String login;
    private int roleId;

    /**
     * Implicit constructor is not public. We have to
     * declare public non-parametric constructor manually.
     */
    public UsersToRolesId() {
    }

    @Override
    public int hashCode() {
        return 17*login.hashCode() + 37*roleId;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof UsersToRolesId))
            return false;
        UsersToRolesId ref = (UsersToRolesId)obj;
        return (this.login.equals(ref.login) && this.roleId == ref.roleId);
    }
}

Ve sorun şu ki, roleName koleksiyonu her zaman boş. Onu işe alamıyorum. Tablo adında @CollectionTable açıklamasında bir hata yaptığımda, hala çalışır. JPA altkomisyonu hiç almıyor. Tablo UsersToRoles ile birleştirilen kullanıcının tablosundan seçim yapar, ancak userRoles tablosuna birleştirme eksik.

Bunu yapabilir miyim? Başka hevesle getirilmiş koleksiyonlar içeren hevesle topluluğun koleksiyonunu alabilir miyim?

1

2 cevap

Haritanız tamamen yanlış. UsersToRoles uygulamasının bir roleId sütunu var. Böylece tek bir role atıfta bulunur. Nasıl bir rol isimleri koleksiyonuna sahip olabilir? Giriş sütunu, varlıkta iki kez eşlenir. Üstelik bu, kullanıcı ve rol kimlikleri için yabancı anahtar olan roleId ve login'den başka bir öznitelik olmadan bana basit birleştirme tablosu gibi görünüyor.

UsersToRoles tablosunu birleşim tablosu olarak kullanarak ManyToMany ilişkilendirmesiyle Kullanıcı ve Rol olmak üzere iki öğeniz olmalıdır. Bu kadar. UsersToRoles tablosu bir varlık olarak eşlenmemelidir: bu bir saf birleşim tablosu.

1
katma

JPA sağlayıcıları genellikle hazır bekletme getirme derinliğini, yani Hazırda Bekletme için hibernate.max_fetch_depth 'i ifade eden bir yapılandırma özelliğine sahiptir. Arttığında daha fazlasını görüp göremeyeceğinizi kontrol edin.

Ayrıca, tasarımınızı düşünün. Bir koleksiyonun alt koleksiyonlarını hevesle almak, yalnızca sınırlı senaryolarda (performans açısından) iyi bir fikir olabilir. Varlığınızı bu şekilde eklediğinizde, tüm kullanım durumlarında hevesli getirme kullanacaksınız. Belki de "tembel" le daha iyi olursun ve JOIN FETCH yan tümcesiyle bir sorguyla hevesle sadece açık bir şekilde getirirsin?

1
katma