Enums জেপিএ মানচিত্র সংগ্রহ


93

সত্তা শ্রেণীর মধ্যে এনামসের সংকলন মানচিত্রের জন্য কি জেপিএতে কোনও উপায় আছে? বা একমাত্র সমাধান হ'ল এনামকে অন্য একটি ডোমেন শ্রেণীর সাথে মোড়ানো এবং সংগ্রহটি মানচিত্রের জন্য ব্যবহার করা?

@Entity
public class Person {
    public enum InterestsEnum {Books, Sport, etc...  }
    //@???
    Collection<InterestsEnum> interests;
}

আমি হাইবারনেট জেপিএ বাস্তবায়ন ব্যবহার করছি, তবে অবশ্যই বাস্তবায়ন অজ্ঞায়নের সমাধান পছন্দ করবো।

উত্তর:


112

হাইবারনেট ব্যবহার করে আপনি করতে পারেন

@CollectionOfElements(targetElement = InterestsEnum.class)
@JoinTable(name = "tblInterests", joinColumns = @JoinColumn(name = "personID"))
@Column(name = "interest", nullable = false)
@Enumerated(EnumType.STRING)
Collection<InterestsEnum> interests;

141
যদি কেউ এখন এটি পড়েন ... @ কালেকশনঅফিলিমেন্টগুলি এখন অবচয় করা হয়েছে, পরিবর্তে এটি ব্যবহার করুন: @ এলিমেন্টকলেকশন

4
: আপনি এই প্রশ্নই answser একটি নমুনা জানতে পারেন stackoverflow.com/q/3152787/363573
স্টিফেন

4
যেহেতু আপনি হাইবারনেটের কথা উল্লেখ করেছেন তাই, আমি ভেবেছিলাম এই উত্তরটি সম্ভবত বিক্রেতা-নির্দিষ্ট হতে পারে তবে আমি মনে করি না যে জয়েন্টবেট ব্যবহার না করা অন্যান্য বাস্তবায়নে সমস্যা সৃষ্টি করে। আমি যা দেখেছি তার থেকে আমি বিশ্বাস করি এর পরিবর্তে কালেকশন টেবিলটি ব্যবহার করা উচিত। আমি আমার উত্তরে এটিই ব্যবহার করেছি এবং এটি আমার পক্ষে কাজ করে (যদিও হ্যাঁ, আমি এখনই হাইবারনেটও ব্যবহার করছি))
spaaarky21

আমি জানি এটি একটি পুরানো থ্রেড, তবে আমরা জাভ্যাক্স.পার্সিস্টেন্স ব্যবহার করে একই ধরণের জিনিসটি প্রয়োগ করছি। যখন আমরা যুক্ত করব: @ এলিমেন্টকোলেকশন (টার্গেটক্লাস = রোলসক্লাস) @ কোলকেশন টেবিল (নাম = "USER_ROLES", জোড় কলামগুলি = @ জয়েন কলাম (নাম = "USER_ID")) @ কলাম (নাম = "আরএলই", nullable = মিথ্যা) @ গণিত ( এনামটাইপ.আরস্টিং) ব্যক্তিগত সেট <রোলস> ভূমিকা; আমাদের ব্যবহারকারীর টেবিলে, পুরো মডেল প্যাকেজের মধ্যে জিনিসগুলি পৃথক হয়ে যায়। আমাদের ব্যবহারকারীর অবজেক্টে, প্রাথমিক কী এর @ আইডিতে ... @ জেনারেটেডভ্যালু জেনারেটর এবং বিল্ডে প্রথম @OneToMany নোংরা ত্রুটি রয়েছে।
লিনাক্সলর্স

এটির জন্য মূল্যবান - আমি যে ত্রুটিগুলি দেখছি তা হ'ল
লিনাক্সলর্স

65

অ্যান্ডির উত্তরের লিঙ্কটি জেপিএ 2-তে "অ-সত্ত্বা" অবজেক্টগুলির ম্যাপিংয়ের দুর্দান্ত সূচনা পয়েন্ট, তবে এনামগুলি ম্যাপিংয়ের ক্ষেত্রে এটি সম্পূর্ণ সম্পূর্ণ নয়। পরিবর্তে আমি এখানে এসেছি।

@Entity
public class Person {
    @ElementCollection(targetClass=InterestsEnum.class)
    @Enumerated(EnumType.STRING) // Possibly optional (I'm not sure) but defaults to ORDINAL.
    @CollectionTable(name="person_interest")
    @Column(name="interest") // Column name in person_interest
    Collection<InterestsEnum> interests;
}

4
দু: খজনকভাবে কিছু "প্রশাসক" কোনও কারণ না দিয়েই উত্তরটি মুছে ফেলার সিদ্ধান্ত নিয়েছেন (এখানে কোর্সের জন্য সমানভাবে)। রেফারেন্সের জন্য এটি datanucleus.org/ প্রোডাক্টস
ডেটা নিউক্লিয়াস

4
সমস্ত আসলে এই আউট প্রয়োজন @ElementCollectionএবং Collection<InterestsEnum> interests; বাকি সম্ভাব্য দরকারী কিন্তু অপ্রয়োজনীয়। উদাহরণস্বরূপ @Enumerated(EnumType.STRING)আপনার ডাটাবেসে মানব পাঠযোগ্য স্ট্রিং রাখে।
CorayThan

4
আপনি সঠিক - এই উদাহরণে, আপনি জড়িত @Columnএর উপর নির্ভর করতে পারেন name। @ কলাম বাদ দিলে কী বোঝানো হয়েছে তা আমি কেবল স্পষ্ট করে বলতে চেয়েছিলাম। অর্ডিনাল একটি ডিফল্ট করার জন্য একটি ভয়ঙ্কর জিনিস হওয়ায় এবং @ গণিত সর্বদা সুপারিশ করা হয়। :)
spaaarky21

আমি এটি উল্লেখ করার মতো মনে করি যে আপনার আসলে person_interest টেবিলের প্রয়োজন
lukaszrys

4
এটি কাজ করতে আমাকে যোগদানের কলাম প্যারামিটারটি যুক্ত করতে হয়েছিল@CollectionTable(name="person_interest", joinColumns = {@JoinColumn(name="person_id")})
টিয়াগো

8

আমি এই সহজ উপায়ে এটি সম্পাদন করতে সক্ষম হয়েছি:

@ElementCollection(fetch = FetchType.EAGER)
Collection<InterestsEnum> interests;

এখানে বর্ণিত হিসাবে অলস লোডিং ইনজায়ালাইজিং ত্রুটি এড়াতে আগ্রহী লোডিংয়ের প্রয়োজন ।


5

অবিচ্ছিন্ন এনামসেট রাখার জন্য আমি java.util.RegularEnumSet এর সামান্য পরিবর্তন ব্যবহার করছি:

@MappedSuperclass
@Access(AccessType.FIELD)
public class PersistentEnumSet<E extends Enum<E>> 
    extends AbstractSet<E> {
  private long elements;

  @Transient
  private final Class<E> elementType;

  @Transient
  private final E[] universe;

  public PersistentEnumSet(final Class<E> elementType) {
    this.elementType = elementType;
    try {
      this.universe = (E[]) elementType.getMethod("values").invoke(null);
    } catch (final ReflectiveOperationException e) {
      throw new IllegalArgumentException("Not an enum type: " + elementType, e);
    }
    if (this.universe.length > 64) {
      throw new IllegalArgumentException("More than 64 enum elements are not allowed");
    }
  }

  // Copy everything else from java.util.RegularEnumSet
  // ...
}

এই শ্রেণিটি এখন আমার সমস্ত এনাম সেটের ভিত্তি:

@Embeddable
public class InterestsSet extends PersistentEnumSet<InterestsEnum> {
  public InterestsSet() {
    super(InterestsEnum.class);
  }
}

এবং এই সেটটি আমি আমার সত্তায় ব্যবহার করতে পারি:

@Entity
public class MyEntity {
  // ...
  @Embedded
  @AttributeOverride(name="elements", column=@Column(name="interests"))
  private InterestsSet interests = new InterestsSet();
}

সুবিধাদি:

  • আপনার কোডে সুরক্ষিত এবং পারফরম্যান্ট এনাম সেট টাইপের সাথে কাজ করা ( java.util.EnumSetকোনও বিবরণের জন্য দেখুন )
  • সেটটি ডাটাবেসে কেবল একটি সংখ্যার কলাম
  • সবকিছু সাধারণ জেপিএ (কোনও সরবরাহকারীর নির্দিষ্ট কাস্টম ধরণের নয় )
  • অন্যান্য সমাধানের তুলনায় একই ধরণের নতুন ক্ষেত্রগুলির সহজ (এবং সংক্ষিপ্ত) ঘোষণা decla

ত্রুটিগুলি:

  • কোড সদৃশ ( RegularEnumSetএবং PersistentEnumSetপ্রায় একই)
    • আপনি ফল মোড়ানো পারে EnumSet.noneOf(enumType)আপনার PersistenEnumSetঘোষণা AccessType.PROPERTYএবং যা প্রতিফলন ব্যবহার দুই এক্সেস পদ্ধতি পড়তে এবং লিখতে elementsক্ষেত্র
  • প্রতিটি এনাম ক্লাসের জন্য একটি অতিরিক্ত সেট শ্রেণীর প্রয়োজন যা একটি অবিরাম সেটগুলিতে সঞ্চয় করা উচিত
    • যদি আপনার অধ্যবসায় সরবরাহকারী কোনও পাবলিক কনস্ট্রাক্টর ছাড়াই এম্বেডেবলগুলিকে সমর্থন করে তবে @Embeddableআপনি PersistentEnumSetঅতিরিক্ত ক্লাসে যোগ এবং ফেলে দিতে পারেন ( ... interests = new PersistentEnumSet<>(InterestsEnum.class);)
  • আপনি অবশ্যই একটি ব্যবহার করতে হবে @AttributeOverride, যেমন আমার উদাহরণে দেওয়া আছে, যদি আপনি PersistentEnumSetআপনার সত্তায় একাধিক পেয়ে থাকেন (অন্যথায় উভয়ই একই কলামে "উপাদান" সংরক্ষণ করা হবে)
  • values()কনস্ট্রাক্টরের প্রতিবিম্ব সহ অ্যাক্সেস অনুকূল নয় (বিশেষত পারফরম্যান্সের দিকে তাকানোর সময়), তবে অন্য দুটি বিকল্পেরও রয়েছে তাদের ত্রুটিগুলি:
    • একটি বাস্তবায়ন যেমন EnumSet.getUniverse()একটি sun.miscশ্রেণীর ব্যবহার করে
    • মানগুলিকে প্যারামিটার হিসাবে সরবরাহ করার ক্ষেত্রে ঝুঁকি রয়েছে যে প্রদত্ত মানগুলি সঠিক মান নয়
  • কেবলমাত্র 64৪ টি মান সহ এনামগুলি সমর্থিত (এটি কি সত্যই একটি ব্যর্থতা?)
    • আপনি এর পরিবর্তে বিগইন্টিজার ব্যবহার করতে পারেন
  • কোনও মানদণ্ডের ক্যোয়ারী বা জেপিকিউএল এ উপাদানগুলির ক্ষেত্রটি ব্যবহার করা সহজ নয়
    • আপনি যদি বাইনারি অপারেটর বা বিটমাস্ক কলামটি উপযুক্ত ফাংশন সহ ব্যবহার করতে পারেন, যদি আপনার ডাটাবেস এটি সমর্থন করে

4

tl; dr একটি সংক্ষিপ্ত সমাধান নিম্নলিখিত হবে:

@ElementCollection(targetClass = InterestsEnum.class)
@CollectionTable
@Enumerated(EnumType.STRING)
Collection<InterestsEnum> interests;

দীর্ঘ উত্তরটি হ'ল এই টীকাগুলির সাহায্যে জেপিএ একটি টেবিল তৈরি করবে যা আগ্রহীকরণের তালিকাটি মূল শ্রেণীর সনাক্তকারীকে চিহ্নিত করবে (এই ক্ষেত্রে পার্সোন.ক্লাস)।

@ এলিমেন্ট সংগ্রহগুলি জেপিএ এনাম সম্পর্কিত তথ্য কোথায় পেতে পারে তা সুনির্দিষ্ট করে

@ কালেকশন টেবিলটি এমন টেবিল তৈরি করুন যা ব্যক্তি থেকে আগ্রহী এনামের সাথে সম্পর্ক রাখে

@ গণিত (এনামটাইপ.স্ট্রেটিং) জেপিএকে এনামকে স্ট্রিং হিসাবে ধরে রাখতে বলুন, এনামটাইপ হতে পারে ORD


এই ক্ষেত্রে আমি এই সংগ্রহটি পরিবর্তন করতে পারি না কারণ এটি পার্সিস্টেনসেট হিসাবে সংরক্ষণ করে যা অনিবার্য।
নিকোলাজ92

আমার ভুল. আমরা একটি সেটারের সাহায্যে এই সেটটি পরিবর্তন করতে পারি।
নিকোলাজ92

0

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


8
এটি কেবল জেপিএ 1.0 এর জন্য বৈধ। জেপিএ ২.০-এ আপনি উপরের চিত্রের মতো @ এলিমেন্টক্লোকেশন টীকাটি ব্যবহার করতে পারেন।
rustyx
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.