জেপিএতে <স্ট্রিং> টাইপের কোনও সম্পত্তি কীভাবে স্থির করবেন?


158

তালিকার ক্ষেত্রের ক্ষেত্রের সাথে সত্তা পাওয়ার সবচেয়ে স্মার্ট উপায় কী?

Command.java

package persistlistofstring;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Persistence;

@Entity
public class Command implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;
    @Basic
    List<String> arguments = new ArrayList<String>();

    public static void main(String[] args) {
        Command command = new Command();

        EntityManager em = Persistence
                .createEntityManagerFactory("pu")
                .createEntityManager();
        em.getTransaction().begin();
        em.persist(command);
        em.getTransaction().commit();
        em.close();

        System.out.println("Persisted with id=" + command.id);
    }
}

এই কোড উত্পাদন করে:

> Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named pu: Provider named oracle.toplink.essentials.PersistenceProvider threw unexpected exception at create EntityManagerFactory: 
> oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException
> Local Exception Stack: 
> Exception [TOPLINK-30005] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException
> Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: sun.misc.Launcher$AppClassLoader@11b86e7
> Internal Exception: javax.persistence.PersistenceException: Exception [TOPLINK-28018] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.EntityManagerSetupException
> Exception Description: predeploy for PersistenceUnit [pu] failed.
> Internal Exception: Exception [TOPLINK-7155] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException
> Exception Description: The type [interface java.util.List] for the attribute [arguments] on the entity class [class persistlistofstring.Command] is not a valid type for a serialized mapping. The attribute type must implement the Serializable interface.
>         at oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:143)
>         at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:169)
>         at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:110)
>         at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
>         at persistlistofstring.Command.main(Command.java:30)
> Caused by: 
> ...

উত্তর:


197

কিছু জেপিএ 2 বাস্তবায়ন ব্যবহার করুন: এটি হাইবারনেটের মতো একটি @ এলিমেটিক্যালেকশন টীকা যুক্ত করে, এটি আপনার প্রয়োজন ঠিক ঠিক করে তোলে। এখানে একটি উদাহরণ আছে

সম্পাদন করা

নীচের মন্তব্যে উল্লিখিত হিসাবে, সঠিক জেপিএ 2 বাস্তবায়ন

javax.persistence.ElementCollection

@ElementCollection
Map<Key, Value> collection;

দেখুন: http://docs.oracle.com/javaee/6/api/javax/persistance/ এলিমেন্টকলেশন html


1
আমার ভুল পাশাপাশি যোগ করার জন্য @ OneToMany টীকা ... এটি সরানোর এবং মাত্র যাব @ ElementCollection এটা কাজ পর
উইলি Mentzel

47

পুরানো থ্রেডটি পুনরুদ্ধার করার জন্য দুঃখিত তবে কেউ যদি আপনার ডাটাবেসে আপনার স্ট্রিং তালিকাগুলিকে এক ক্ষেত্র হিসাবে সংরক্ষণ করেন এমন বিকল্প সমাধানের সন্ধান করা উচিত, আমি কীভাবে এটি সমাধান করেছি তা এখানে। এটির মত একটি রূপান্তরকারী তৈরি করুন:

import java.util.Arrays;
import java.util.List;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
    private static final String SPLIT_CHAR = ";";

    @Override
    public String convertToDatabaseColumn(List<String> stringList) {
        return String.join(SPLIT_CHAR, stringList);
    }

    @Override
    public List<String> convertToEntityAttribute(String string) {
        return Arrays.asList(string.split(SPLIT_CHAR));
    }
}

এখন এটি আপনার প্রতিষ্ঠানে এটির মতো ব্যবহার করুন:

@Convert(converter = StringListConverter.class)
private List<String> yourList;

ডাটাবেসে আপনার তালিকা foo; bar; foobar হিসাবে সংরক্ষণ করা হবে এবং আপনার জাভা অবজেক্টে আপনি সেই স্ট্রিং সহ একটি তালিকা পাবেন।

আশা করি এটি কারও সহায়ক হবে।


এটি কি সেই ক্ষেত্রের সামগ্রীর দ্বারা ফিল্টারিং ফলাফলের জন্য জেপিএ সংগ্রহস্থলগুলির সাথে কাজ করবে?
করে_ডন্ট_বুলি_মে_স_ও_লর্ডস

1
@ প্লিজ_ডন্ট_বুলি_মে_সো_লর্ডস এটি ব্যবহারের ক্ষেত্রে কম উপযুক্ত কারণ আপনার ডেটাবেস "foo; বার; ফুবার" হিসাবে ডাটাবেসে থাকবে। আপনি যদি ডেটাটির জন্য জিজ্ঞাসা করতে চান তবে সম্ভবত একটি এলিমেন্টক্লোকশন + জয়েন্ট টেবিল হ'ল আপনার পরিস্থিতির দিকে যাওয়ার উপায়।
জোনক ভ্যান ডার কোগেল

এর অর্থ হ'ল SPLIT_CHARআপনার স্ট্রিংটিতে আপনার কোনও উপস্থিতি থাকতে পারে না ।
ক্রাশ

@ ক্রাশ যে সঠিক। যদিও অবশ্যই আপনি এটির জন্য উদাহরণস্বরূপ আপনার স্ট্রিংটি এনকোড করে যথাযথভাবে সীমাবদ্ধ করার পরে অনুমতি দিতে পারেন। তবে আমি এখানে সমাধান যে সমাধানটি পোস্ট করেছি তা মূলত সাধারণ ব্যবহারের ক্ষেত্রে ব্যবহৃত হয়; আরও জটিল পরিস্থিতিতে সম্ভবত আপনি একটি এলিমেন্টক্লোকশন + জয়েন্ট টেবিল দিয়ে আরও ভাল ভাড়া করতে পারেন
জোনক ভ্যান ডার

আপনার কোড ঠিক করুন। আমি এটিকে 'লাইব্রেরি কোড' হিসাবে বিবেচনা করি তাই এটি প্রতিরক্ষামূলক হওয়া উচিত যেমন কমপক্ষে এটি নাল চেক করা উচিত
ZZ 5

30

এই উত্তরটি প্রাক-জেপিএ 2 বাস্তবায়ন করা হয়েছিল, আপনি যদি জেপিএ 2 ব্যবহার করে থাকেন তবে উপরের এলিমেন্টকোলেকশন উত্তরটি দেখুন:

কোনও মডেল অবজেক্টের অভ্যন্তরের অবজেক্টের তালিকাকে অন্য একটি অবজেক্টের সাথে "ওয়ানটোম্যানি" সম্পর্ক হিসাবে বিবেচনা করা হয়। যাইহোক, একটি স্ট্রিং (নিজেই) ওয়ান-টু-মেন সম্পর্কের অনুমোদিত গ্রাহক নয়, কারণ এতে কোনও আইডি নেই।

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

বিকল্পভাবে, আপনি আপনার তালিকাটি @ ট্রান্সিয়েন্টে রূপান্তর করতে পারেন এবং আপনার শ্রেণিতে আরও একটি ক্ষেত্র (আরজিস্টোরেশন) যুক্ত করতে পারেন যা হয় কোনও ভিআরচারার () বা সিএলওবি। এরপরে আপনাকে 3 টি ফাংশন যুক্ত করতে হবে: এর মধ্যে 2 টি সমান এবং আপনার স্ট্রিংগুলির তালিকাটি একটি স্ট্রিং (আরগস্টোরারেজে) রূপান্তরিত করা উচিত যাতে আপনি সহজেই তাদের আলাদা করতে পারেন। @PrePersist এবং @PreUpdate এর সাহায্যে এই দুটি ফাংশন (যে প্রত্যেকে একই কাজটি করে) এনেট করুন অবশেষে, তৃতীয় ফাংশন যুক্ত করুন যা আর্টস্টোরেজকে আবার স্ট্রিংয়ের তালিকায় বিভক্ত করে এবং এটিকে @ পোষ্টলয়েড এনেট করুন। আপনি যখনই কমান্ডটি সঞ্চয় করতে যান এটি আপনার সিএলওবিটিকে স্ট্রিংগুলির সাথে আপডেট রাখবে এবং আপনি ডিবিতে সঞ্চয় করার আগে আরগস্টোরেশন ক্ষেত্রটি আপডেট রাখবেন।

আমি এখনও প্রথম কেস করার পরামর্শ দিই। এটি পরে বাস্তব সম্পর্কের জন্য ভাল অনুশীলন।


অ্যারেলিস্ট <স্ট্রিং> থেকে কমা বিচ্ছিন্ন মানগুলির সাথে স্ট্রিংয়ে পরিবর্তন করা আমার পক্ষে কাজ করেছে।
ক্রিস ডেল

2
তবে এই ক্ষেত্রটি অনুসন্ধান করার সময় এটি আপনাকে (imho) কুৎসিত বিবৃতিগুলির মতো ব্যবহার করতে বাধ্য করে।
হুইস্কিসিয়ার

হ্যাঁ, আমি যেমন বলেছি ... প্রথম বিকল্পটি করুন, এটি আরও ভাল। আপনি যদি এটি করতে নিজেকে না আনতে পারেন তবে বিকল্প 2 কাজ করতে পারে।
বিলজেমসদেব

15

হাইবারনেট সহ জাভা পার্সেস্টানস অনুসারে

টীকাগুলির সাথে মান ধরণের সংগ্রহ ম্যাপিং [...]। লেখার সময় এটি জাভা দৃistence়তা মানের অংশ নয়

আপনি যদি হাইবারনেট ব্যবহার করে থাকেন তবে আপনি এমন কিছু করতে পারেন:

@org.hibernate.annotations.CollectionOfElements(
    targetElement = java.lang.String.class
)
@JoinTable(
    name = "foo",
    joinColumns = @JoinColumn(name = "foo_id")
)
@org.hibernate.annotations.IndexColumn(
    name = "POSITION", base = 1
)
@Column(name = "baz", nullable = false)
private List<String> arguments = new ArrayList<String>();

আপডেট: দ্রষ্টব্য, এটি এখন জেপিএ 2 এ উপলব্ধ।


12

আমরা এটিও ব্যবহার করতে পারি।

@Column(name="arguments")
@ElementCollection(targetClass=String.class)
private List<String> arguments;

1
সম্ভবত প্লিজ @ জোয়েন্ট টেবিল।
phil294

9

জেপিএর হাইবারনেট বাস্তবায়নটি ব্যবহার করার সময়, আমি খুঁজে পেয়েছি যে কেবলমাত্র তালিকার পরিবর্তে অ্যারেরলিস্ট হিসাবে প্রকারটি ঘোষণার মাধ্যমে হাইবারনেটটি ডেটা তালিকা সংরক্ষণ করতে দেয়।

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

@Entity
public class Command implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    ArrayList<String> arguments = new ArrayList<String>();


}

2
ধন্যবাদ। সমস্ত জেপিএ প্রয়োগের সাথে এই কাজ করে, অ্যারেলিস্টটি সিরিয়ালাইজযোগ্য একটি বিএলওবি ক্ষেত্রে সংরক্ষণ করা হয়। এই পদ্ধতির সমস্যাগুলি হ'ল 1) বিএলওবি আকারটি স্থির 2) আপনি অ্যারে উপাদানগুলি সন্ধান করতে বা সূচী করতে পারেন 3) জাভা সিরিয়ালাইজেশন ফর্ম্যাট সম্পর্কে সচেতন কেবলমাত্র একজন ক্লায়েন্ট এই উপাদানগুলি পড়তে পারেন।
আন্দ্রে ফ্রান্সিয়া

আপনি যদি এই পদ্ধতির সাথে @OneToMany @ManyToOne @ElementCollectionএটি ব্যবহার করে থাকেন তবে আপনাকে Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElementsসার্ভার স্টার্টআপে ব্যতিক্রম দেয়। হাইবারনেটস আপনি সংগ্রহ ইন্টারফেস ব্যবহার করতে চান।
পরমবীর সিং কারওয়াল

9

আমার একই সমস্যা ছিল তাই আমি প্রদত্ত সম্ভাব্য সমাধানটি বিনিয়োগ করেছি তবে শেষ পর্যন্ত আমি আমার '; স্ট্রিংয়ের পৃথক তালিকা।

তাই আমার আছে

// a ; separated list of arguments
String arguments;

public List<String> getArguments() {
    return Arrays.asList(arguments.split(";"));
}

এইভাবে ডাটাবেস সারণিতে তালিকাটি সহজেই পঠনযোগ্য / সম্পাদনাযোগ্য;


1
এটি সম্পূর্ণ বৈধ তবে আপনার অ্যাপ্লিকেশনটির বৃদ্ধি এবং স্কিমা বিবর্তন বিবেচনা করুন। (কাছাকাছি) ভবিষ্যতের কিছু সময় আপনি অবশেষে সত্তা ভিত্তিক পদ্ধতির স্যুইচ করতে পারেন।
হুইস্কিসিয়ার

আমি সম্মত, এটি সম্পূর্ণ বৈধ। তবে আমি কোডটি বাস্তবায়নের পাশাপাশি যুক্তিটি সম্পূর্ণরূপে পর্যালোচনা করার পরামর্শ দিই। স্ট্রিং যদি argumentsঅ্যাক্সেস অনুমতিগুলির একটি তালিকা হয় তবে বিশেষ চরিত্র, ক separator, থাকা বিশেষাধিকারের ক্রমবর্ধমান আক্রমণে ঝুঁকিপূর্ণ হতে পারে।
থাং ফাম

1
এটি সত্যই খারাপ পরামর্শ, আপনার স্ট্রিংয়ে এটি থাকতে পারে ;যা আপনার অ্যাপ্লিকেশনটিকে ভেঙে দেবে।
agilob

9

দেখে মনে হয় যে কোনও উত্তরই এটির জন্য সর্বাধিক গুরুত্বপূর্ণ সেটিংস অনুসন্ধান করে নি @ElementCollection ম্যাপিংয়ের ।

আপনি যখন এই টীকা সহ কোনও তালিকা মানচিত্র করবেন এবং জেপিএ / হাইবারনেট স্বয়ংক্রিয়ভাবে টেবিল, কলাম ইত্যাদি তৈরি করতে দিন, এটি স্বয়ংক্রিয়ভাবে উত্পন্ন নামও ব্যবহার করবে।

সুতরাং, আসুন একটি প্রাথমিক উদাহরণ বিশ্লেষণ করুন:

@Entity
@Table(name = "sample")
public class MySample {

    @Id
    @GeneratedValue
    private Long id;

    @ElementCollection // 1
    @CollectionTable(name = "my_list", joinColumns = @JoinColumn(name = "id")) // 2
    @Column(name = "list") // 3
    private List<String> list;

}
  1. প্রাথমিক @ElementCollectionটীকা (যেখানে আপনি পরিচিত fetchএবং সংজ্ঞায়িত করতে পারেনtargetClass পছন্দগুলি )
  2. @CollectionTableটীকা খুব দরকারী যখন এটি সেইসাথে সারণি উত্পন্ন করা হবে একটি নাম দিতে, মত সংজ্ঞা আসে joinColumns, foreignKey'এস, indexes, uniqueConstraints, ইত্যাদি
  3. @Columnকলামের নাম নির্ধারণ করা গুরুত্বপূর্ণ varcharযা তালিকার মান সঞ্চয় করবে store

উত্পাদিত ডিডিএল সৃষ্টিটি হ'ল:

-- table sample
CREATE TABLE sample (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (id)
);

-- table my_list
CREATE TABLE IF NOT EXISTS my_list (
  id bigint(20) NOT NULL,
  list varchar(255) DEFAULT NULL,
  FOREIGN KEY (id) REFERENCES sample (id)
);

4
আমি এই সমাধানটি পছন্দ করি কারণ এটি একমাত্র প্রস্তাবিত সমাধান যা টেবিল কাঠামোগুলি সহ পুরো বিবরণ দেয় এবং আমাদের আলাদা আলাদা টীকাগুলির প্রয়োজন কেন তা ব্যাখ্যা করে।
জুলিয়েন ক্রোনেগ

6

ঠিক আছে আমি এর একটু দেরী জানি। তবে সেই সাহসী আত্মাদের জন্য যারা সময় কেটে যাওয়ার সাথে সাথে এটি দেখতে পাবে।

ডকুমেন্টেশন লিখিত হিসাবে :

@ বেসিক: একটি ডাটাবেস কলামে ম্যাপিংয়ের সহজতম ধরণ। বেসিক টীকাগুলি নিম্নলিখিত ধরণের যে কোনও স্থির সম্পত্তি বা দৃষ্টান্তের ভেরিয়েবলের জন্য প্রয়োগ করা যেতে পারে: জাভা আদিম ধরণের, [...], এনামস এবং জাভা.আই.এস.রাইজিয়েবল কার্যকরকারী অন্য কোনও প্রকারের।

গুরুত্বপূর্ণ অংশটি টাইপ যা সিরিয়ালাইজেবল প্রয়োগ করে

সুতরাং এখন পর্যন্ত সমাধানের সর্বাধিক সহজ এবং সহজতমতম म्हणजे কেবল তালিকা (বা কোনও সিরিয়ালাইজযোগ্য ধারক) এর পরিবর্তে অ্যারেলিস্ট ব্যবহার করা:

@Basic
ArrayList<Color> lovedColors;

@Basic
ArrayList<String> catNames;

তবে মনে রাখবেন যে এটি সিস্টেম সিরিয়ালাইজেশন ব্যবহার করবে, সুতরাং এটি কিছু দাম সহ আসবে যেমন:

  • যদি সিরিয়ালযুক্ত অবজেক্টের মডেলটি পরিবর্তিত হয়, আপনি ডেটা পুনরুদ্ধার করতে পারবেন না

  • সঞ্চিত প্রতিটি উপাদানগুলির জন্য ছোট ওভারহেড যুক্ত করা হয়।

সংক্ষেপে

পতাকা বা কয়েকটি উপাদান সংরক্ষণ করা বেশ সহজ, তবে আমি বড় আকার ধারণ করতে পারে এমন ডেটা সংরক্ষণ করার জন্য এটি পুনরুদ্ধার করব না।


এটি চেষ্টা করে দেখলেও স্কিল টেবিলটি ডেটাটাইপটিকে একটি ক্ষুদ্রব্লব করে তোলে। এটি স্ট্রিংগুলির তালিকাটি সন্নিবেশ করা এবং পুনরুদ্ধার করে খুব অসুবিধে করে না? অথবা জেপিএ আপনার জন্য স্বয়ংক্রিয়ভাবে সিরিয়ালাইজ এবং ডিসিশায়ালাইজ করে?
Dzhao

3

থিয়াগো উত্তরটি সঠিক, প্রশ্নের সাথে আরও সুনির্দিষ্ট নমুনা যুক্ত করে, @ এলিমেন্টক্লিকেশন আপনার ডাটাবেসে নতুন টেবিল তৈরি করবে, তবে দুটি টেবিল ম্যাপিং ছাড়াই, এর অর্থ হল যে সংগ্রহটি সত্তার সংকলন নয়, তবে সাধারণ ধরণের সংগ্রহ (স্ট্রিংস ইত্যাদি) is ।) বা এম্বেডযোগ্য উপাদানগুলির একটি সংকলন (ক্লাসটি @ এম্বেডেবলের সাথে টিকা দেওয়া হয়েছে) )।

এখানে নমুনা তালিকা জিদ হয় স্ট্রিং

@ElementCollection
private Collection<String> options = new ArrayList<String>();

এখানে কাস্টম অবজেক্টের তালিকা ধরে রাখতে নমুনা দেওয়া আছে

@Embedded
@ElementCollection
private Collection<Car> carList = new ArrayList<Car>();

এই ক্ষেত্রে আমাদের ক্লাস এম্বেডেবল করতে হবে

@Embeddable
public class Car {
}

3

@ কনভার্টার এবং স্ট্রিংটোকেনাইজার ব্যবহার করে সেট সংরক্ষণ করার সমাধান এখানে। @ জোনক-ভ্যান-ডের-কোজেল সলিউশনটির বিপরীতে আরও কিছু চেক ।

আপনার সত্তা শ্রেণিতে:

@Convert(converter = StringSetConverter.class)
@Column
private Set<String> washSaleTickers;

StringSetConverter:

package com.model.domain.converters;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

@Converter
public class StringSetConverter implements AttributeConverter<Set<String>, String> {
    private final String GROUP_DELIMITER = "=IWILLNEVERHAPPEN=";

    @Override
    public String convertToDatabaseColumn(Set<String> stringList) {
        if (stringList == null) {
            return new String();
        }
        return String.join(GROUP_DELIMITER, stringList);
    }

    @Override
    public Set<String> convertToEntityAttribute(String string) {
        Set<String> resultingSet = new HashSet<>();
        StringTokenizer st = new StringTokenizer(string, GROUP_DELIMITER);
        while (st.hasMoreTokens())
            resultingSet.add(st.nextToken());
        return resultingSet;
    }
}

1

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

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