जेपीए इकाई मेटामोडेल कैसे उत्पन्न करें?


94

CriteriaQuery JPA 2.0 के साथ जुड़े प्रकार की सुरक्षा की भावना में मेटामोडेल संस्थाओं के प्रतिनिधित्व का समर्थन करने के लिए एक एपीआई भी है ।

क्या किसी को इस एपीआई के पूरी तरह कार्यात्मक कार्यान्वयन के बारे में पता है (मेटामॉडल उत्पन्न करने के लिए मैन्युअल रूप से मेटामॉडल कक्षाएं बनाने का विरोध करने के लिए)? यह भयानक होगा अगर कोई इसे ग्रहण में स्थापित करने के चरणों को भी जानता है (मुझे लगता है कि यह एनोटेशन प्रोसेसर स्थापित करने के रूप में सरल है, लेकिन आप कभी नहीं जानते हैं)।

संपादित करें: बस हाइबरनेट जेपीए 2 मेटामोडेल जनरेटर में ठोकर खाई । लेकिन समस्या बनी हुई है क्योंकि मुझे जार के लिए कोई डाउनलोड लिंक नहीं मिल रहा है।

संपादित करें 2: जब से मैंने यह प्रश्न पूछा है, तब से अब तक बीत चुका है, लेकिन मैंने सोचा था कि मैं वापस आऊंगा और SourceForge पर हाइबरनेट JPA मॉडल जेनरेटर परियोजना के लिए एक लिंक जोड़ूंगा

जवाबों:


87

यह भयानक होगा अगर कोई इसे ग्रहण में स्थापित करने के चरणों को भी जानता है (मुझे लगता है कि यह एनोटेशन प्रोसेसर स्थापित करने जितना आसान है, लेकिन आप कभी नहीं जानते हैं)

हाँ यही है। यहां विभिन्न JPA 2.0 कार्यान्वयन के लिए कार्यान्वयन और निर्देश दिए गए हैं:

EclipseLink

हाइबरनेट

OpenJPA

DataNucleus


नवीनतम हाइबरनेट कार्यान्वयन यहां उपलब्ध है:

एक पुराना हाइबरनेट कार्यान्वयन इस प्रकार है:


1
DataNucleus लिंक मृत है।
कार्ल रिक्टर

1
हाइबरनेट लिंक भी मृत है
फ्रीलांसर

43

कृपया jpa-metamodels-with-maven-example पर एक नज़र डालें ।

हाइबरनेट

  • हमें चाहिए org.hibernate.org:hibernate-jpamodelgen
  • प्रोसेसर वर्ग है org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor

एक निर्भरता के रूप में हाइबरनेट करें

    <dependency>
      <groupId>org.hibernate.orm</groupId>
      <artifactId>hibernate-jpamodelgen</artifactId>
      <version>${version.hibernate-jpamodelgen}</version>
      <scope>provided</scope>
    </dependency>

एक प्रोसेसर के रूप में हाइबरनेट करें

      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <compilerArguments>-AaddGeneratedAnnotation=false</compilerArguments> <!-- suppress java.annotation -->
              <processors>
                <processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
              </processors>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>${version.hibernate-jpamodelgen}</version>
          </dependency>
        </dependencies>
      </plugin>

OpenJPA

  • हमें चाहिए org.apache.openjpa:openjpa
  • प्रोसेसर वर्ग है org.apache.openjpa.persistence.meta.AnnotationProcessor6
  • OpenJPA के लिए अतिरिक्त तत्व की आवश्यकता लगती है <openjpa.metamodel>true<openjpa.metamodel>

OpenJPA एक निर्भरता के रूप में

  <dependencies>
    <dependency>
      <groupId>org.apache.openjpa</groupId>
      <artifactId>openjpa</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <compilerArgs>
            <arg>-Aopenjpa.metamodel=true</arg>
          </compilerArgs>
        </configuration>
      </plugin>
    </plugins>
  </build>

प्रोसेसर के रूप में OpenJPA

      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <id>process</id>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <processors>
                <processor>org.apache.openjpa.persistence.meta.AnnotationProcessor6</processor>
              </processors>
              <optionMap>
                <openjpa.metamodel>true</openjpa.metamodel>
              </optionMap>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.apache.openjpa</groupId>
            <artifactId>openjpa</artifactId>
            <version>${version.openjpa}</version>
          </dependency>
        </dependencies>
      </plugin>

EclipseLink

  • हमें चाहिए org.eclipse.persistence:org.eclipse.persistence.jpa.modelgen.processor
  • प्रोसेसर वर्ग है org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor
  • एक्लिप्सलिंक की आवश्यकता होती है persistence.xml

एक निर्भरता के रूप में ग्रहण

  <dependencies>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
      <scope>provided</scope>
    </dependency>

एक प्रोसेसर के रूप में ग्रहण

    <plugins>
      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <processors>
                <processor>org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor</processor>
              </processors>
              <compilerArguments>-Aeclipselink.persistencexml=src/main/resources-${environment.id}/META-INF/persistence.xml</compilerArguments>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
            <version>${version.eclipselink}</version>
          </dependency>
        </dependencies>
      </plugin>

DataNucleus

  • हमें चाहिए org.datanucleus:datanucleus-jpa-query
  • प्रोसेसर वर्ग है org.datanucleus.jpa.query.JPACriteriaProcessor

एक निर्भरता के रूप में DataNucleus

  <dependencies>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-jpa-query</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>

DataNucleus एक प्रोसेसर के रूप में

      <plugin>
        <groupId>org.bsc.maven</groupId>
        <artifactId>maven-processor-plugin</artifactId>
        <executions>
          <execution>
            <id>process</id>
            <goals>
              <goal>process</goal>
            </goals>
            <phase>generate-sources</phase>
            <configuration>
              <processors>
                <processor>org.datanucleus.jpa.query.JPACriteriaProcessor</processor>
              </processors>
            </configuration>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-jpa-query</artifactId>
            <version>${version.datanucleus}</version>
          </dependency>
        </dependencies>
      </plugin>

3
बस स्पष्ट होना, उत्पन्न सामान eclipselink साथ इस्तेमाल किया जा सकता है, भले ही आप इसे उत्पन्न करने के लिए हाइबरनेट का उपयोग करें, मैं सके NetBeans 8 से मेटा मॉडल पैदा करते हैं और मेरा सामान उत्पन्न करने के लिए एक Maven परीक्षण परियोजना बनाने के लिए किया था
कल्पेश सोनी

@ymajoros क्या यह SO में, something is recommendedबिना कहने के लिए मना किया गया है IMHO? मैं किसी और की ओर से प्रतिनिधित्व नहीं कर रहा हूं।
जिन क्वॉन

1
Btw, EclipseLink के लिए सॉर्टर का जवाब देखें। यह वह कॉन्फ़िगरेशन है जो मैं वर्षों से उपयोग कर रहा हूं और यह पूरी तरह से काम करता है। stackoverflow.com/questions/3037593/…
यमजोरस

क्या यह कार्यान्वयन विशिष्ट नहीं है, मैं ग्रहण के साथ हाइबरनेट उत्पन्न मेटामोडेल का उपयोग करने की कोशिश करता हूं और NullPointerException प्राप्त करता हूं
Michał Ziobro

@ymajoros अभी भी एक की जरूरत है persistence.xml, है ना?
जिन क्वोन

20

दली के माध्यम से ग्रहण का जेपीए 2.0 समर्थन (जो "जेईई डेवलपर्स के लिए ग्रहण आईडीई" में शामिल है) का अपना स्वयं का मेटामॉडल जनरेटर है जिसे ग्रहण के साथ एकीकृत किया गया है।

  1. पैकेज एक्सप्लोरर में अपनी परियोजना का चयन करें
  2. प्रॉपर्टीज पर जाएं -> JPA डायलॉग
  3. Canonical metamodel (JPA 2.0) समूह से स्रोत फ़ोल्डर का चयन करें
  4. चयनित स्रोत फ़ोल्डर में मेटामॉडल कक्षाएं उत्पन्न करने के लिए लागू करें बटन पर क्लिक करें

यहां छवि विवरण दर्ज करें

यह किसी भी जेपीए प्रदाता पर काम करना चाहिए क्योंकि उत्पन्न वर्ग मानक हैं।

यह भी देखें यहाँ


क्या इस प्रक्रिया को खुद से दूर करने का कोई तरीका है? यह मज़बूती से मेरे लिए
मेटामॉडल का

6

एक्लिप्सलिंक के लिए, केवल निम्न निर्भरता मेटामोडेल उत्पन्न करने के लिए पर्याप्त है। और कुछ नहीं चाहिए।

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.1</version>
        <scope>provided</scope>
    </dependency>


@ बर्थेलोमस आपका नोट गलत है । EclipseLink 2.5.1+ असूचीबद्ध संस्थाओं के लिए भी मेटामॉडल कक्षाएं उत्पन्न करेगा, बस <exclude-unlisted-classes>false</exclude-unlisted-classes>दृढ़ता में निर्दिष्ट करें । मिक्स
मिशेल

ध्यान दें कि eclipselink बिना उत्पन्न नहीं होगीpersistence.xml
जिन

5

प्रदाता के रूप में हाइबरनेट के लिए जो कि सबसे आम IMHO है:

ग्रैडल, मावेन जैसे बिल्ड टूल्स के मामले में, आपको क्लासपैथ और कंपाइलर स्तर> = 1.6 में हाइबरनेट जेपीए 2 मेटामॉडल जेनरेटर जार रखने की आवश्यकता है। आपको प्रोजेक्ट बनाने की जरूरत है और मेटामॉडल अपने आप उत्पन्न हो जाएगा।

आईडीई ग्रहण के मामले में 1. गोटो प्रोजेक्ट-> गुण-> जावा कंपाइलर-> एनोटेशन प्रोसेसिंग और इसे सक्षम करें। 2. एनोटेशन प्रोसेसिंग का विस्तार करें-> फैक्ट्री पाथ-> एक्सटर्नल जार जोड़ें Hibernate JPA 2 मेटामॉडल जेनरेटर जार को नए जोड़े गए जार की जाँच करें और ओके कहें। साफ और निर्माण किया!

लिंक हाइबरनेट जेपीए 2 मेटामोडेल जेनरेटर जार लिंक से मावेन रेपो https://mvnrepository.com/artifact/org.hibernate/hibernate-jpamodelgen


मेरे मामले में जोड़ रहा है <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <scope>compile</scope> </dependency> </dependencies> में pom.xml को पर्याप्त था।
ल्यु 55

क्या मुझे मावेन और एक्लिप्स का उपयोग करते समय दोनों कॉन्फ़िगरेशन की आवश्यकता है?
मेल्कॉर

भले ही हाइबरनेट- jpamodelgen पोम में जोड़ा गया था, मुझे यह करना पड़ा और यह काम किया
फ्रीलांसर

3

चूंकि यह एक बहुत ही सामान्य प्रश्न है, इसलिए मैंने यह लेख लिखा है , जिस पर यह उत्तर आधारित है।

चलो हमारे आवेदन निम्नलिखित का उपयोग करता है मान लेते हैं Post, PostComment, PostDetails, और Tagसंस्थाओं, जो एक एक-से-कई रूप है, एक-से-एक, और कई-से-अनेक तालिका रिश्तों :

जेपीए मानदंड मेटामोडेल

जेपीए क्राइटेरिया मेटामोडेल कैसे उत्पन्न करें

hibernate-jpamodelgenहाइबरनेट ORM द्वारा प्रदान की उपकरण परियोजना संस्थाओं को स्कैन और जेपीए मानदंड Metamodel उत्पन्न करने के लिए इस्तेमाल किया जा सकता। तुम सब करने की ज़रूरत है निम्नलिखित जोड़ने annotationProcessorPathके लिए maven-compiler-pluginMaven में pom.xmlविन्यास फाइल:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven-compiler-plugin.version}</version>
    <configuration>
        <annotationProcessorPaths>
            <annotationProcessorPath>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-jpamodelgen</artifactId>
                <version>${hibernate.version}</version>
            </annotationProcessorPath>
        </annotationProcessorPaths>
    </configuration>
</plugin>

अब, जब परियोजना संकलित की जाती है, तो आप देख सकते हैं कि targetफ़ोल्डर में, निम्नलिखित जावा कक्षाएं उत्पन्न होती हैं:

> tree target/generated-sources/
target/generated-sources/
└── annotations
    └── com
        └── vladmihalcea
            └── book
                └── hpjp
                    └── hibernate
                        ├── forum
                           ├── PostComment_.java
                           ├── PostDetails_.java
                           ├── Post_.java
                           └── Tag_.java

टैग इकाई मेटामॉडल

यदि Tagइकाई निम्नानुसार मैप की गई है:

@Entity
@Table(name = "tag")
public class Tag {

    @Id
    private Long id;

    private String name;

    //Getters and setters omitted for brevity
}

Tag_Metamodel वर्ग इस तरह उत्पन्न होता है:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Tag.class)
public abstract class Tag_ {

    public static volatile SingularAttribute<Tag, String> name;
    public static volatile SingularAttribute<Tag, Long> id;

    public static final String NAME = "name";
    public static final String ID = "id";
}

SingularAttributeबुनियादी के लिए प्रयोग किया जाता है idऔर name Tagजेपीए इकाई गुण।

पोस्ट इकाई मेटामॉडल

Postइकाई इस तरह मैप किया गया है:

@Entity
@Table(name = "post")
public class Post {

    @Id
    private Long id;

    private String title;

    @OneToMany(
        mappedBy = "post",
        cascade = CascadeType.ALL,
        orphanRemoval = true
    )
    private List<PostComment> comments = new ArrayList<>();

    @OneToOne(
        mappedBy = "post",
        cascade = CascadeType.ALL,
        fetch = FetchType.LAZY
    )
    @LazyToOne(LazyToOneOption.NO_PROXY)
    private PostDetails details;

    @ManyToMany
    @JoinTable(
        name = "post_tag",
        joinColumns = @JoinColumn(name = "post_id"),
        inverseJoinColumns = @JoinColumn(name = "tag_id")
    )
    private List<Tag> tags = new ArrayList<>();

    //Getters and setters omitted for brevity
}

Postइकाई दो बुनियादी गुण होते हैं, idऔरtitle एक एक-से-कई, commentsसंग्रह, एक एक-से-एक detailsसंघ है, और एक बहुत-से-अनेक tagsसंग्रह।

Post_Metamodel वर्ग इस प्रकार उत्पन्न होता है:

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Post.class)
public abstract class Post_ {

    public static volatile ListAttribute<Post, PostComment> comments;
    public static volatile SingularAttribute<Post, PostDetails> details;
    public static volatile SingularAttribute<Post, Long> id;
    public static volatile SingularAttribute<Post, String> title;
    public static volatile ListAttribute<Post, Tag> tags;

    public static final String COMMENTS = "comments";
    public static final String DETAILS = "details";
    public static final String ID = "id";
    public static final String TITLE = "title";
    public static final String TAGS = "tags";
}

बुनियादी idऔर titleविशेषताओं, साथ ही साथ एक-से-एक detailsएसोसिएशन, द्वारा प्रतिनिधित्व किया जाता हैSingularAttribute थोड़ी देरcomments और tagsसंग्रह को जेपीए द्वारा दर्शाया जाता है ListAttribute

PostDetails इकाई Metamodel

PostDetailsइकाई इस तरह मैप किया गया है:

@Entity
@Table(name = "post_details")
public class PostDetails {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "created_on")
    private Date createdOn;

    @Column(name = "created_by")
    private String createdBy;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    @JoinColumn(name = "id")
    private Post post;

    //Getters and setters omitted for brevity
}

SingularAttributeसंबंधित PostDetails_मेटामोडेल वर्ग में जेपीए द्वारा सभी इकाई विशेषताओं का प्रतिनिधित्व किया जा रहा है :

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(PostDetails.class)
public abstract class PostDetails_ {

    public static volatile SingularAttribute<PostDetails, Post> post;
    public static volatile SingularAttribute<PostDetails, String> createdBy;
    public static volatile SingularAttribute<PostDetails, Long> id;
    public static volatile SingularAttribute<PostDetails, Date> createdOn;

    public static final String POST = "post";
    public static final String CREATED_BY = "createdBy";
    public static final String ID = "id";
    public static final String CREATED_ON = "createdOn";
}

पोस्टकॉममेंट इकाई मेटामॉडल

PostCommentइस प्रकार मैप किया गया है:

@Entity
@Table(name = "post_comment")
public class PostComment {

    @Id
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Post post;

    private String review;

    //Getters and setters omitted for brevity
}

और, सभी इकाई विशेषताओं को SingularAttributeसंबंधित PostComments_मेटामोडेल वर्ग में जेपीए द्वारा दर्शाया गया है :

@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(PostComment.class)
public abstract class PostComment_ {

    public static volatile SingularAttribute<PostComment, Post> post;
    public static volatile SingularAttribute<PostComment, String> review;
    public static volatile SingularAttribute<PostComment, Long> id;

    public static final String POST = "post";
    public static final String REVIEW = "review";
    public static final String ID = "id";
}

जेपीए मानदंड मेटामोडेल का उपयोग करना

जेपीए मेटामॉडल के बिना, एक मानदंड एपीआई क्वेरी जिसे PostCommentउनके संबंधित Postशीर्षक द्वारा फ़िल्टर की गई संस्थाओं को प्राप्त करने की आवश्यकता होती है :

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<PostComment> query = builder.createQuery(PostComment.class);
Root<PostComment> postComment = query.from(PostComment.class);

Join<PostComment, Post> post = postComment.join("post");

query.where(
    builder.equal(
        post.get("title"),
        "High-Performance Java Persistence"
    )
);

List<PostComment> comments = entityManager
    .createQuery(query)
    .getResultList();

ध्यान दें कि हमने उदाहरण postबनाते समय स्ट्रिंग शाब्दिक का उपयोग किया था Join, और हमने इसका उपयोग कियाtitle संदर्भित करते समय स्ट्रिंग शाब्दिक काPost title

जेपीए मेटामॉडल हमें हार्ड-कोडिंग इकाई विशेषताओं से बचने की अनुमति देता है, जैसा कि निम्नलिखित उदाहरण द्वारा चित्रित किया गया है:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<PostComment> query = builder.createQuery(PostComment.class);
Root<PostComment> postComment = query.from(PostComment.class);

Join<PostComment, Post> post = postComment.join(PostComment_.post);

query.where(
    builder.equal(
        post.get(Post_.title),
        "High-Performance Java Persistence"
    )
);

List<PostComment> comments = entityManager
    .createQuery(query)
    .getResultList();

यदि आप कोडकोटा जैसे कोड पूरा करने वाले टूल का उपयोग कर रहे हैं, तो जेपीए मानदंड एपीआई प्रश्न लिखना बहुत आसान है। की जाँच करें इस लेख Codota आईडीई प्लगइन के बारे में अधिक जानकारी के लिए।

या, मान लें कि हम और फ़िल्टर करते समय डीटीओ प्रोजेक्शन लाना चाहते हैंPost titlePostDetails createdOn विशेषताओं ।

हम मेटामोडेल का उपयोग ज्वाइन की विशेषताओं को बनाते समय कर सकते हैं, साथ ही डीटीओ प्रोजेक्शन कॉलम एलियास का निर्माण करते समय या इकाई विशेषताओं को संदर्भित करते समय हमें फ़िल्टर करने की आवश्यकता होती है:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<Object[]> query = builder.createQuery(Object[].class);

Root<PostComment> postComment = query.from(PostComment.class);
Join<PostComment, Post> post = postComment.join(PostComment_.post);

query.multiselect(
    postComment.get(PostComment_.id).alias(PostComment_.ID),
    postComment.get(PostComment_.review).alias(PostComment_.REVIEW),
    post.get(Post_.title).alias(Post_.TITLE)
);

query.where(
    builder.and(
        builder.like(
            post.get(Post_.title),
            "%Java Persistence%"
        ),
        builder.equal(
            post.get(Post_.details).get(PostDetails_.CREATED_BY),
            "Vlad Mihalcea"
        )
    )
);

List<PostCommentSummary> comments = entityManager
    .createQuery(query)
    .unwrap(Query.class)
    .setResultTransformer(Transformers.aliasToBean(PostCommentSummary.class))
    .getResultList();

बिल्कुल सटीक?


0

ठीक है, जो मैंने यहां पढ़ा है, उसके आधार पर, मैंने इसे EclipseLink के साथ किया और मुझे परियोजना के लिए प्रोसेसर की निर्भरता को annotationProcessorPathकंपाइलर प्लगइन के एक तत्व के रूप में डालने की आवश्यकता नहीं थी ।

    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <annotationProcessorPaths>
                <annotationProcessorPath>
                    <groupId>org.eclipse.persistence</groupId>
                    <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
                    <version>2.7.7</version>
                </annotationProcessorPath>
            </annotationProcessorPaths>
            <compilerArgs>
                <arg>-Aeclipselink.persistencexml=src/main/resources/META-INF/persistence.xml</arg>
            </compilerArgs>
        </configuration>
    </plugin>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.