سؤال

كيف تجعل من ذلك أن الجدول user_roles يحدد عمودين (userID, رقم تعريف role) كما مركب أساسي.يجب أن تكون سهلة, فقط لا يمكن أن نتذكر/العثور على.

في user كيان:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_roles")
public List<RoleDAO> getRoles() {
    return roles;
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getUserID() {
    return userID;
}

في roles كيان:

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_roles")
public List<UserDAO> getUsers() {
    return users;
}

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Integer getRoleID() {
    return roleID;
}

شكرا لك.

** مزيد من المعلومات

حتى لا يكون هناك جدول ثالث user_roles (السيارات التي تم إنشاؤها بواسطة أعلاه) أن يأخذ userID من user الكيان roleID من roles الكيان.الآن أنا بحاجة إلى تلك عمودين في إنشاء الجدول (user_roles) إلى مركب أساسي.

هل كانت مفيدة؟

المحلول

ولقد كان بالفعل بعض الإجابات جيدة هنا حول كيفية القيام بالضبط كما تسأل ..

لإشارة اسمحوا لي أن أذكر الطريقة الموصى بها للقيام بذلك في السبات بدلا من ذلك، وهو أن استخدام مفتاح بديل كمفتاح أساسي، وبمناسبة مفاتيح العمل كما في NaturalId:

<اقتباس فقرة>   

وعلى الرغم من أننا نوصي باستخدام   مفاتيح بديلة كما المفاتيح الأساسية، يمكنك   يجب أن تحاول تحديد مفاتيح الطبيعية   لجميع الكيانات. مفتاح الطبيعي هو   الممتلكات أو مجموعة من الخصائص   التي هي فريدة من نوعها وغير باطل. أنه   أيضا غير قابل للتغيير. تعيين خصائص   مفتاح الطبيعي داخل    جزء. السبات سوف   توليد مفتاح فريد ضروري و   القيود nullability، ونتيجة ل   نتيجة لذلك، سوف التعيين أن يكون أكثر   ، توثيق النفس.

     

من المستحسن أن تقوم بتنفيذ   يساوي () وشفرة التجزئة () لمقارنة   الخصائص الأساسية الطبيعية للكيان.

في التعليمات البرمجية، باستخدام والشروح، وهذا من شأنه أن ننظر بشيء من هذا القبيل:

@Entity
public class UserRole {
  @Id
  @GeneratedValue
  private long id;

  @NaturalId
  private User user;
  @NaturalId
  private Role role;
}

وباستخدام هذا سيوفر لك الكثير من الصداع على الطريق، كما عليك معرفة عندما يكون لديك كثير من الأحيان إلى مرجع / تعيين المفتاح الأساسي يتكون.

ولقد وجدت هذا بالطريقة الصعبة، وفي النهاية قدم للتو عن القتال ضد السبات وبدلا من ذلك قررت الذهاب مع تدفق. أنا أفهم تماما أن هذا قد لا يكون ممكنا في الحالة الخاصة بك، كما قد يكون التعامل مع البرامج القديمة أو التبعيات، ولكن أردت فقط أن أذكر ذلك للرجوع إليها في المستقبل. (<م> إذا كنت لا يمكن استخدامها ربما شخص آخر يمكن !)

نصائح أخرى

في أجل تلبية الاحتياجات الخاصة بك، يمكنك تعيينManyToMany ك رسم الخرائطOneToMany. وبهذه الطريقة، سوف USER_ROLE تحتوي على كل USER_ID وROLE_ID كمفتاح أساسي مركب

وسوف تظهر لك كيف:

@Entity
@Table(name="USER")
public class User {

    @Id
    @GeneratedValue
    private Integer id;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="joinedUserRoleId.user")
    private List<JoinedUserRole> joinedUserRoleList = new ArrayList<JoinedUserRole>();

    // no-arg required constructor
    public User() {}

    public User(Integer id) {
        this.id = id;
    }

    // addRole sets up bidirectional relationship
    public void addRole(Role role) {
        // Notice a JoinedUserRole object
        JoinedUserRole joinedUserRole = new JoinedUserRole(new JoinedUserRole.JoinedUserRoleId(this, role));

        joinedUserRole.setUser(this);
        joinedUserRole.setRole(role);

        joinedUserRoleList.add(joinedUserRole);
    }

}

@Entity
@Table(name="USER_ROLE")
public class JoinedUserRole {

    public JoinedUserRole() {}

    public JoinedUserRole(JoinedUserRoleId joinedUserRoleId) {
        this.joinedUserRoleId = joinedUserRoleId;
    }

    @ManyToOne
    @JoinColumn(name="USER_ID", insertable=false, updatable=false)
    private User user;

    @ManyToOne
    @JoinColumn(name="ROLE_ID", insertable=false, updatable=false)
    private Role role;

    @EmbeddedId
    // Implemented as static class - see bellow
    private JoinedUserRoleId joinedUserRoleId;

    // required because JoinedUserRole contains composite id
    @Embeddable
    public static class JoinedUserRoleId implements Serializable {

        @ManyToOne
        @JoinColumn(name="USER_ID")
        private User user;

        @ManyToOne
        @JoinColumn(name="ROLE_ID")
        private Role role;

        // required no arg constructor
        public JoinedUserRoleId() {}

        public JoinedUserRoleId(User user, Role role) {
            this.user = user;
            this.role = role;
        }

        public JoinedUserRoleId(Integer userId, Integer roleId) {
            this(new User(userId), new Role(roleId));
        }

        @Override
        public boolean equals(Object instance) {
            if (instance == null)
                return false;

            if (!(instance instanceof JoinedUserRoleId))
                return false;

            final JoinedUserRoleId other = (JoinedUserRoleId) instance;
            if (!(user.getId().equals(other.getUser().getId())))
                return false;

            if (!(role.getId().equals(other.getRole().getId())))
                return false;

            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 47 * hash + (this.user != null ? this.user.hashCode() : 0);
            hash = 47 * hash + (this.role != null ? this.role.hashCode() : 0);
            return hash;
        }

    }

}

وتذكر

<اقتباس فقرة>   

إذا كائن حصوله على تصنيف من   المعرف، أو مفتاح مركب، و   المعرف يجب تعيين ل   يعترض سبيل المثال قبل استدعاء حفظ ().

وهكذا أنشأنا منشئ JoinedUserRoleId مثل هذا واحد من أجل العناية بها

public JoinedUserRoleId(User user, Role role) {
    this.user = user;
    this.role = role;
}

وأخيرا الطبقة دور

@Entity
@Table(name="ROLE")
public class Role {

    @Id
    @GeneratedValue
    private Integer id;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="JoinedUserRoleId.role")
    private List<JoinedUserRole> joinedUserRoleList = new ArrayList<JoinedUserRole>();

    // no-arg required constructor
    public Role() {}

    public Role(Integer id) {
        this.id = id;
    }

    // addUser sets up bidirectional relationship
    public void addUser(User user) {
        // Notice a JoinedUserRole object
        JoinedUserRole joinedUserRole = new JoinedUserRole(new JoinedUserRole.JoinedUserRoleId(user, this));

        joinedUserRole.setUser(user);
        joinedUserRole.setRole(this);

        joinedUserRoleList.add(joinedUserRole);
    }

}

وفقا لاختبار ذلك، دعنا نكتب ما يلي

User user = new User();
Role role = new Role();

// code in order to save a User and a Role
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

Serializable userId  = session.save(user);
Serializable roleId = session.save(role);

session.getTransaction().commit();
session.clear();
session.close();

// code in order to set up bidirectional relationship
Session anotherSession = HibernateUtil.getSessionFactory().openSession();
anotherSession.beginTransaction();

User savedUser = (User) anotherSession.load(User.class, userId);
Role savedRole = (Role) anotherSession.load(Role.class, roleId);

// Automatic dirty checking
// It will set up bidirectional relationship
savedUser.addRole(savedRole);

anotherSession.getTransaction().commit();
anotherSession.clear();
anotherSession.close();

وإشعار وفقا لقانون فوق أي إشارة إلى الدرجة JoinedUserRole.

إذا كنت ترغب في استرداد JoinedUserRole، جرب ما يلي

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

Integer userId;
Integer roleId;

// Lets say you have set up both userId and roleId
JoinedUserRole joinedUserRole = (JoinedUserRole) session.get(JoinedUserRole.class, new JoinedUserRole.JoinedUserRoleId(userId, roleId));

// some operations

session.getTransaction().commit();
session.clear();
session.close();

والتحيات،

وتتم مفاتيح المركبة باستخدامIdClass (في الاتجاه الآخر يستخدمEmbeddedId وEmbeddable لست متأكدا أي واحد كنت تبحث عن) وIdClass على النحو التالي

@Entity
@IdClass(CategoryPK.class)
public class Category {
    @Id
    protected String name;

    @Id
    protected Date createDate;

}

public class CategoryPK implements Serializable {

    String name;

    Date createDate;

    public boolean equals(object other) {
        //implement a equals that the PP can use to determine 
        //how the CategoryPK object can be identified.
    }

    public int hashCode(){
        return Super.hashCode();
    }
}

وبلدي الفئة هنا سيكون user_roles واسم وسوف createDate يكون المستخدم ورقم تعريف Role بك

شكرا تحسين على سؤالك ...و مع الأخذ بعين الاعتبار الاقتراحات.

(آسف, فمن الغريب بعض الشيء أن كنت postfix الكيانات مع Daos ، لكنها ليست النقطة.)

أنا لست متأكد من أن هناك أي مشكلة اليسار :

  • اثنين من الكيانات لك أن تصف كل واحدة PK ، وليس زوج من.
  • رابط جدول ليس له كيان المقابلة ، فإنه يتم تعريف implicitely من قبل اثنين من الكيانات ManyToMany العلاقة.إذا كنت بحاجة إلى كيان ثالث ، ManyToMany لزوج من OneToMany و ManyToOne العلاقات.

كان لي نفس المشكلة مع المفاتيح الأساسية.أنا أيضا أعرف الحل مع @ادراجها و @EmbeddedId الدرجة.ولكن أردت فقط الحل بسيط مع الشروح.

حسنا لقد وجدت التنوير من خلال هذه المقالة: http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-many-to-many-using-annotations-1.html

وها هو السحر:

يقوم هذا بإنشاء مفتاح أساسي على الانضمام إلى الجدول:

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="classA_classB")
private Set<ClassA> classesA;

هذا ممتلئا لا تولد المفتاح الأساسي على الانضمام إلى الجدول:

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="classA_classB")
private List<ClassA> classesA;

على الأقل في بيئة

علما بأن الفرق هو استخدام مجموعة أو قائمة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top