জেপিএ একাধিক এমবেডেড ক্ষেত্র


84

জেপিএ সত্তা শ্রেণীর পক্ষে দুটি এম্বেডেড ( @Embedded) ক্ষেত্র থাকতে পারে ? একটি উদাহরণ হবে:

@Entity
public class Person {
    @Embedded
    public Address home;

    @Embedded
    public Address work;
}

public class Address {
    public String street;
    ...
}

এই ক্ষেত্রে Personএকটিতে দুটি Addressদৃষ্টান্ত থাকতে পারে - বাড়ি এবং কাজ। আমি হাইবারনেটের প্রয়োগের সাথে জেপিএ ব্যবহার করছি। যখন আমি হাইবারনেট সরঞ্জামগুলি ব্যবহার করে স্কিমা তৈরি করি তখন এটি কেবল একটি এম্বেড করে Address। আমি যা চাই তা দুটি এম্বেড হওয়া Addressদৃষ্টান্ত each আমি জানি @AttributeOverrides, তবে এর জন্য প্রতিটি বৈশিষ্ট্য পৃথকভাবে ওভাররাইড করা দরকার। এম্বেড থাকা বস্তু ( Address) বড় হয়ে গেলে প্রতিটি কলাম পৃথকভাবে ওভাররাইড করা দরকার হলে এটি জটিল হয়ে উঠতে পারে।

উত্তর:


29

আপনি যদি একই সত্তায় দু'বার একই এম্বেডযোগ্য অবজেক্টের ধরণটি পেতে চান তবে কলামের নাম ডিফল্টটি কাজ করবে না: কমপক্ষে একটি কলামের স্পষ্ট থাকতে হবে। হাইবারনেট EJB3 টিপকে ছাড়িয়ে যায় এবং আপনাকে নামস্ট্রেটজির মাধ্যমে ডিফল্ট মেকানিজম উন্নত করতে দেয়। DefaultComponentSafeNamingStrategy ডিফল্ট EJB3NamingStrategy এর তুলনায় একটি ছোট উন্নতি যা এম্বেড থাকা বস্তুগুলিকে একই সত্তায় দু'বার ব্যবহার করা গেলেও খেলাপি হতে দেয়।

হাইবারনেট অ্যানোটেশন ডক থেকে: http://docs.jboss.org/hibernate/stable/annotations/references/en/html_single/#d0e714


89

এটি করার জেনেরিক জেপিএ উপায়টি হ'ল @ অ্যাট্রিবিউটওভারাইড। এটি EclipseLink এবং হাইবারনেট উভয় ক্ষেত্রেই কাজ করা উচিত।

@Entity 
public class Person {
  @AttributeOverrides({
    @AttributeOverride(name="street",column=@Column(name="homeStreet")),
    ...
  })
  @Embedded public Address home;

  @AttributeOverrides({
    @AttributeOverride(name="street",column=@Column(name="workStreet")),
    ...
  })
  @Embedded public Address work;
  }

  @Embeddable public class Address {
    @Basic public String street;
    ...
  }
}

9
নোট যা name="street"সম্পত্তির নাম উল্লেখ করে, কলামের নাম নয়।
বার্ট সোয়েনেনহুইস

এটিকে কী "ক্লানকি" হিসাবে বিবেচনা করা হয় কারণ শ্রেণীর ঠিকানা (রাস্তার নাম সম্বলিত ক্ষেত্রের নাম) এর মতো অন্তরঙ্গ বিষয়গুলি ব্যক্তির বিকাশকারীকে জানতে হবে?
এমবিএমস্ট

বাহ, সুতরাং টীকা ব্যবহার করে আমাকে এগুলি পুনরাবৃত্তি করতে হবে। ডাব্লুটিএফ আমি স্ট্রিং হোমস্ট্রিট ব্যবহার করে নিজে নিজে পুরো এম্বেডড ক্লাসটি নিজেই ঘোষণা করতে পারি; পরিবর্তে স্ট্রিং ওয়ার স্ট্রিট, সম্ভবত আরও নির্দোষ।
মিমি

6

এলিপ্স লিঙ্কটি ব্যবহার করার সময়, অ্যাট্রিবিউট ওভাররাইড ব্যবহারের বিকল্প একটি সেশনকাস্টমাইজার ব্যবহার করার জন্য। এটি একসাথে সমস্ত সত্তার জন্য সমস্যাটি সমাধান করে:

public class EmbeddedFieldNamesSessionCustomizer implements SessionCustomizer {

@SuppressWarnings("rawtypes")
@Override
public void customize(Session session) throws Exception {
    Map<Class, ClassDescriptor> descriptors = session.getDescriptors();
    for (ClassDescriptor classDescriptor : descriptors.values()) {
        for (DatabaseMapping databaseMapping : classDescriptor.getMappings()) {
            if (databaseMapping.isAggregateObjectMapping()) {
                AggregateObjectMapping m = (AggregateObjectMapping) databaseMapping;
                Map<String, DatabaseField> mapping = m.getAggregateToSourceFields();

                ClassDescriptor refDesc = descriptors.get(m.getReferenceClass());
                for (DatabaseMapping refMapping : refDesc.getMappings()) {
                    if (refMapping.isDirectToFieldMapping()) {
                        DirectToFieldMapping refDirectMapping = (DirectToFieldMapping) refMapping;
                        String refFieldName = refDirectMapping.getField().getName();
                        if (!mapping.containsKey(refFieldName)) {
                            DatabaseField mappedField = refDirectMapping.getField().clone();
                            mappedField.setName(m.getAttributeName() + "_" + mappedField.getName());
                            mapping.put(refFieldName, mappedField);
                        }
                    }

                }
            }

        }
    }
}

}

+1 বর্গক্ষেত্রে এটিকে নিয়ন্ত্রণ করতে সক্ষম হবার জন্য এটি একটি বিবরণকারী কাস্টোমাইজার হিসাবে পেয়ে ভাল লাগবে তবে আমি হোস্ট শ্রেণীর বর্ণনাকারী কাস্টমাইজারের মধ্যে এম্বেড থাকা শ্রেণীর ক্লাসডেস্কিটারের অ্যাক্সেসের কোনও উপায় খুঁজে পাইনি।
oulenz

4
আমি এখন যে বিকল্পটি ব্যবহার করছি classDescriptor.getJavaClass()তা হ'ল আমি যে ক্লাসগুলিকে প্রভাবিত করতে চাই তার তালিকার বিপরীতে সেশন কাস্টমাইজারে যাচাই করা।
ওউলেঞ্জ

1

আপনি হাইবারনেট ব্যবহার করছেন এমন ক্ষেত্রে আপনি আলাদা আলাদা নামকরণের স্কিমও ব্যবহার করতে পারেন যা অভিন্ন এমবেডেড ক্ষেত্রগুলির জন্য কলামগুলিতে অনন্য উপসর্গ যুক্ত করে। দেখুন স্বয়ংক্রিয়ভাবে @Embeddable ক্লাস জন্য কলাম নামে একটি উপসর্গ যোগ করুন

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