অতিরিক্ত কলাম (গুলি) দিয়ে বহু-বহু সংখ্যক সমিতি টেবিল ম্যাপিং


130

আমার ডাটাবেসটিতে 3 টি টেবিল রয়েছে: ব্যবহারকারী এবং পরিষেবা সত্তাদের একাধিক থেকে অনেক বেশি সম্পর্ক রয়েছে এবং SERVICE_USER টেবিলের সাথে নিম্নলিখিত হিসাবে যোগদান করা হয়েছে:

USERS - SERVICE_USER - SERVICES

SERVICE_USER টেবিলটিতে অতিরিক্ত ব্লক কলাম রয়েছে।

এই ধরনের ম্যাপিংয়ের সর্বোত্তম উপায় কী? এগুলি আমার সত্ত্বার ক্লাস

@Entity
@Table(name = "USERS")
public class User implements java.io.Serializable {

private String userid;
private String email;

@Id
@Column(name = "USERID", unique = true, nullable = false,)
public String getUserid() {
return this.userid;
}

.... some get/set methods
}

@Entity
@Table(name = "SERVICES")
public class CmsService implements java.io.Serializable {
private String serviceCode;

@Id
@Column(name = "SERVICE_CODE", unique = true, nullable = false, length = 100)
public String getServiceCode() {
return this.serviceCode;
}
.... some additional fields and get/set methods
}

আমি এই উদাহরণটি অনুসরণ করেছি http://giannigar.wordpress.com/2009/09/04/m ... ব্যবহার করে-jpa / এখানে কিছু পরীক্ষার কোড দেওয়া হয়েছে:

User user = new User();
user.setEmail("e2");
user.setUserid("ui2");
user.setPassword("p2");

CmsService service= new CmsService("cd2","name2");

List<UserService> userServiceList = new ArrayList<UserService>();

UserService userService = new UserService();
userService.setService(service);
userService.setUser(user);
userService.setBlocked(true);
service.getUserServices().add(userService);

userDAO.save(user);

সমস্যাটি হ'ল হাইবারনেট ব্যবহারকারী অবজেক্ট এবং ইউজার সার্ভিস একটিকে অব্যাহত রাখে। CmsService অবজেক্টের সাথে কোনও সাফল্য নেই

আমি ইগ্রার আনতে চেষ্টা করেছি - কোন অগ্রগতি নেই

উপরে বর্ণিত ম্যাপিংয়ের সাথে আমি যে আচরণটি প্রত্যাশা করছি তা অর্জন করা সম্ভব?

অতিরিক্ত কলাম সহ অনেকগুলি টেবিলের সাথে ম্যাপিংয়ের আরও কিছু মার্জিত উপায় হতে পারে?

উত্তর:


192

যেহেতু SERVICE_USER টেবিলটি খাঁটি যোগদানের টেবিল নয়, তবে অতিরিক্ত ক্রিয়ামূলক ক্ষেত্র রয়েছে (অবরুদ্ধ), আপনাকে অবশ্যই এটি সত্তা হিসাবে মানচিত্র তৈরি করতে হবে এবং অনেকগুলি ব্যবহারকারী এবং পরিষেবাদির মধ্যে বহু সংযোগকে দুটি ওয়ানটোমো সংস্থায় বিভক্ত করতে হবে: একটি ব্যবহারকারীর অনেকগুলি ব্যবহারকারী সার্ভিস রয়েছে, এবং একটি পরিষেবাদিতে অনেকগুলি ব্যবহারকারীর পরিষেবা রয়েছে।

আপনি আমাদের সর্বাধিক গুরুত্বপূর্ণ অংশটি দেখান নি: আপনার সত্তার মধ্যে সম্পর্কের ম্যাপিং এবং প্রারম্ভিককরণ (উদাহরণস্বরূপ যে অংশে আপনার সমস্যা রয়েছে)। সুতরাং আমি আপনাকে দেখাব যে এটি দেখতে কেমন হবে।

আপনি যদি সম্পর্কগুলিকে দ্বিপক্ষীয় করে তোলেন, আপনার এইভাবে হওয়া উচিত

class User {
    @OneToMany(mappedBy = "user")
    private Set<UserService> userServices = new HashSet<UserService>();
}

class UserService {
    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "service_code")
    private Service service;

    @Column(name = "blocked")
    private boolean blocked;
}

class Service {
    @OneToMany(mappedBy = "service")
    private Set<UserService> userServices = new HashSet<UserService>();
}

যদি আপনি আপনার সম্পর্কের উপর কোনও ক্যাসকেড না রাখেন তবে আপনাকে অবশ্যই সমস্ত সত্তা অবিচ্ছিন্ন / সংরক্ষণ করতে হবে। যদিও সম্পর্কের কেবল নিজস্ব পক্ষই (এখানে, ইউজার সার্ভিস পক্ষ) অবশ্যই শুরু করা উচিত, তবে উভয় পক্ষই একত্রিত হয়েছে তা নিশ্চিত করে নেওয়াও একটি ভাল অনুশীলন।

User user = new User();
Service service = new Service();
UserService userService = new UserService();

user.addUserService(userService);
userService.setUser(user);

service.addUserService(userService);
userService.setService(service);

session.save(user);
session.save(service);
session.save(userService);

2
কেবল যোগ করার জন্য .. যদিও এটি আমার মতে সবচেয়ে ভাল উপায় (আমি সবসময় পারফরম্যান্সের কারণে সত্তা হিসাবে এফকে মালিকানাধীন জিনিসটি মানচিত্র করতে পছন্দ করি), এটি আসলে একমাত্র উপায় নয়। আপনি একটি উপাদান হিসাবে SERVICE_USER টেবিল থেকে মানগুলিও ম্যাপ করতে পারেন (জেপিএ এম্বেডযোগ্য @ElementCollectionযাকে বলে) এবং ব্যবহারকারী এবং পরিষেবা সত্ত্বা উভয় থেকে (বা উভয়) ব্যবহার করতে পারেন ।
স্টিভ ইবারসোল

6
ইউজার সার্ভিস সারণীর প্রাথমিক কী সম্পর্কে কী? এটি ব্যবহারকারী এবং পরিষেবা বিদেশী কীগুলির সমন্বয় হওয়া উচিত। এটা কি ম্যাপ করা আছে?
জোনাস গ্রাগার

24
আমি এটা না। সংমিশ্রিত কীগুলি বেদনাদায়ক, অকার্যকর এবং হাইবারনেট যৌগিক কীগুলি ব্যবহার না করার পরামর্শ দেয়। অন্য কোনও সত্তা হিসাবে কেবল একটি স্বয়ংক্রিয় উত্পাদিত আইডি ব্যবহার করুন, এবং জীবন অনেক সহজ হবে। এর একীকরণ নিশ্চিত করতে [userFK, serviceFK], একটি অনন্য বাধা ব্যবহার করুন use
জেবি নিজত

1
@ গ্যারিকিফার্ট: আপনার নিজের কোড এবং নিজের ম্যাপিংয়ের মাধ্যমে আপনার নিজের প্রশ্ন জিজ্ঞাসা করুন।
জেবি নিজেট

1
@ জিস্ট্যাকওভারফ্লো: হাইবারনেট ৪ এ বিষয়ে কোনও পরিবর্তন করে না। আমি সত্যিই দেখতে পাচ্ছি না যে এটি কীভাবে ব্যর্থ।
জেবি নিজত

5

আমি এক্সএমএল ফাইল কনফিগারেশনে হাইবারনেট সহ অতিরিক্ত কলাম (গুলি) সহ অনেকগুলি থেকে বহু সংযোগ টেবিলকে ম্যাপ করার একটি উপায় অনুসন্ধান করি।

ধরে নেওয়া হচ্ছে দুটি অতিরিক্ত টেবিল 'একটি' এবং 'সি' রয়েছে যার সাথে 'এক্সট্রা' নামের একটি কলামের সাথে অনেকের অনেকেরই যোগ রয়েছে। কারণ আমি কোনও সম্পূর্ণ উদাহরণ খুঁজে পাইনি, এখানে আমার কোড। আশা করি এটি সাহায্য করবে :)।

প্রথমে এখানে জাভা অবজেক্টস রয়েছে।

public class A implements Serializable{  

    protected int id;
    // put some others fields if needed ...   
    private Set<AC> ac = new HashSet<AC>();

    public A(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Set<AC> getAC() {
        return ac;
    }

    public void setAC(Set<AC> ac) {
        this.ac = ac;
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        final int prime = 97;
        int result = 1;
        result = prime * result + id;
        return result;
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof A))
            return false;
        final A other = (A) obj;
        if (id != other.getId())
            return false;
        return true;
    }

}

public class C implements Serializable{

    protected int id;
    // put some others fields if needed ...    

    public C(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        final int prime = 98;
        int result = 1;
        result = prime * result + id;
        return result;
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof C))
            return false;
        final C other = (C) obj;
        if (id != other.getId())
            return false;
        return true;
    }

}

এখন, আমাদের সমিতি টেবিল তৈরি করতে হবে। প্রথম পদক্ষেপটি একটি জটিল প্রাথমিক কী (a.id, c.id) উপস্থাপন করে এমন একটি বস্তু তৈরি করা।

public class ACId implements Serializable{

    private A a;
    private C c;

    public ACId() {
        super();
    }

    public A getA() {
        return a;
    }
    public void setA(A a) {
        this.a = a;
    }
    public C getC() {
        return c;
    }
    public void setC(C c) {
        this.c = c;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((a == null) ? 0 : a.hashCode());
        result = prime * result
                + ((c == null) ? 0 : c.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ACId other = (ACId) obj;
        if (a == null) {
            if (other.a != null)
                return false;
        } else if (!a.equals(other.a))
            return false;
        if (c == null) {
            if (other.c != null)
                return false;
        } else if (!c.equals(other.c))
            return false;
        return true;
    }
}

এখন এসোসিয়েশন অবজেক্টটি নিজে তৈরি করি।

public class AC implements java.io.Serializable{

    private ACId id = new ACId();
    private String extra;

    public AC(){

    }

    public ACId getId() {
        return id;
    }

    public void setId(ACId id) {
        this.id = id;
    }

    public A getA(){
        return getId().getA();
    }

    public C getC(){
        return getId().getC();
    }

    public void setC(C C){
        getId().setC(C);
    }

    public void setA(A A){
        getId().setA(A);
    }

    public String getExtra() {
        return extra;
    }

    public void setExtra(String extra) {
        this.extra = extra;
    }

    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        AC that = (AC) o;

        if (getId() != null ? !getId().equals(that.getId())
                : that.getId() != null)
            return false;

        return true;
    }

    public int hashCode() {
        return (getId() != null ? getId().hashCode() : 0);
    }
}

এই মুহুর্তে, হাইবারনেট এক্সএমএল কনফিগারেশন সহ আমাদের সমস্ত ক্লাস মানচিত্র করার সময় এসেছে।

এএইচবিএম.এক্সএমএল এবং সিএইচএক্সএমএল.এক্সএমএল (একইভাবে শান্ত)।

<class name="A" table="a">
        <id name="id" column="id_a" unsaved-value="0">
            <generator class="identity">
                <param name="sequence">a_id_seq</param>
            </generator>
        </id>
<!-- here you should map all others table columns -->
<!-- <property name="otherprop" column="otherprop" type="string" access="field" /> -->
    <set name="ac" table="a_c" lazy="true" access="field" fetch="select" cascade="all">
        <key>
            <column name="id_a" not-null="true" />
        </key>
        <one-to-many class="AC" />
    </set>
</class>

<class name="C" table="c">
        <id name="id" column="id_c" unsaved-value="0">
            <generator class="identity">
                <param name="sequence">c_id_seq</param>
            </generator>
        </id>
</class>

এবং তারপরে অ্যাসোসিয়েশন ম্যাপিং ফাইল, a_c.hbm.xML।

<class name="AC" table="a_c">
    <composite-id name="id" class="ACId">
        <key-many-to-one name="a" class="A" column="id_a" />
        <key-many-to-one name="c" class="C" column="id_c" />
    </composite-id>
    <property name="extra" type="string" column="extra" />
</class>

পরীক্ষার জন্য কোডের নমুনা এখানে।

A = ADao.get(1);
C = CDao.get(1);

if(A != null && C != null){
    boolean exists = false;
            // just check if it's updated or not
    for(AC a : a.getAC()){
        if(a.getC().equals(c)){
            // update field
            a.setExtra("extra updated");
            exists = true;
            break;
        }
    }

    // add 
    if(!exists){
        ACId idAC = new ACId();
        idAC.setA(a);
        idAC.setC(c);

        AC AC = new AC();
        AC.setId(idAC);
        AC.setExtra("extra added"); 
        a.getAC().add(AC);
    }

    ADao.save(A);
}

2

যেমনটি আগেই বলা হয়েছিল, জেপিএর সাথে অতিরিক্ত কলাম করার সুযোগ পাওয়ার জন্য আপনাকে একক ম্যানটোম্যানির সম্পর্কের পরিবর্তে দুটি ওয়ানটোম্যান সমিতি দরকার। আপনি স্বতঃজাতীয় মান সহ একটি কলামও যুক্ত করতে পারেন; এইভাবে, এটি কার্যকর হলে টেবিলের প্রাথমিক কী হিসাবে কাজ করতে পারে।

উদাহরণস্বরূপ, অতিরিক্ত শ্রেণীর প্রয়োগের কোডটি দেখতে এমন হওয়া উচিত:

@Entity
@Table(name = "USER_SERVICES")
public class UserService{

    // example of auto-generated ID
    @Id
    @Column(name = "USER_SERVICES_ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long userServiceID;



    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "USER_ID")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "SERVICE_ID")
    private Service service;



    // example of extra column
    @Column(name="VISIBILITY")    
    private boolean visibility;



    public long getUserServiceID() {
        return userServiceID;
    }


    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Service getService() {
        return service;
    }

    public void setService(Service service) {
        this.service = service;
    }

    public boolean getVisibility() {
        return visibility;
    }

    public void setVisibility(boolean visibility) {
        this.visibility = visibility;
    }

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.