Басқа қызығушылық тудыратын жинақтар бар адамдарға қызығушылығын жинау

Мен M: N-ге байланыстырылған элемент мен стрингтер арасындағы қатынас. Пайдаланушы бірнеше рөлге ие болуы мүмкін және әрбір рөл бірден көп пайдаланушыға тағайындалуы мүмкін. Рөл тек қана жол. Рөлдер екі бағанмен кестеде бар: roleId және roleName .

Мен екі бірлікті құрдым, бірақ оны жұмыс істей алмаймын. Бірінші тұлға пайдаланушы болып табылады:

@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;
    }
}

Екінші - қосылу кестесімен байланысты субъект:

@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);
    }
}

Мәселе мынада, roleName жинағы әрдайым нөлге тең. Мен оны жұмыс істей алмаймын. @CollectionTable аннотациясында кесте атауында қате жібергенде, ол әлі де жұмыс істейді. JPA ішкі топтаманы мүлдем алып келмейді. Пайдаланушы кестесінен UsersToRoles кестесімен қосылған, бірақ кестеге қосылу userRoles жоқ.

Мен мұны ешқашан қабылдай аламын ба? Қызығушылық тудыратын тағы бір коллекцияны қамтитын объектілерді жігерлендіре аламын ба?

1

2 жауаптар

Сіздің картаңыз дұрыс емес. UsersToRoles бар roleId бағаны бар. Осылайша ол бір ғана рөлге қатысты. Рөл аттарының жинағы қалай болуы мүмкін? Кіру бағаны ұйымда екі рет салыстырылады. Сонымен қатар, бұл мен үшін қарапайым қосылу кестесіне ұқсас, пайдаланушы идентификаторы мен роліне сәйкес шетел кілттері болып табылатын roleId және кіруден басқа ешқандай төлсип жоқ.

UsersToRoles кестесін біріктіру кестесі ретінде пайдалану арқылы User және Role ManyToMany

1
қосылды

JPA провайдерлері, әдетте, әдепкі күйге келтірілетін ендік тереңдігін, яғни hibernate.max_fetch_depth > Гибернация үшін Hypernate параметрін көрсететін теңшелім сипаты бар. Сіз оны ұлғайтқанда көп көре аласыз ба.

Сондай-ақ, сіздің дизайныңыз туралы ойланыңыз. Коллекцияның ішкі коллекцияларын қызықтырып алу шектеулі сценарийлерде (өнімділікпен) жақсы идея болуы мүмкін. Осындай нысанды түсіндіріп бергенде, сіз барлық пайдалану жағдайларында қызықты сатылымды қолдана аласыз. Мүмкін, сіз «жалқау» және «JOIN FETCH» сөйлемімен сұраныспен оны тек қана ашық түрде қабылдай аласыз ба?

1
қосылды