openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jeff <jeffrey.blatt...@yahoo.com>
Subject Re: composite ID w/ another composite ID as a field
Date Mon, 02 Apr 2007 20:01:29 GMT
hi craig, thanks ...

your suggestion would imply that that BookId can be converted to and from a String object,
right? i checked the spec, and i expected to find a requirement to have a toString() method
and a string constructor that can work in unison to this end, but it's not there. maybe i
am still thinking JDO.

anyway, i did try that, 

public class PageId implements Serializable {
    private int number;
    private String book;

and i get: 

Caused by: <4|true|0.9.6-incubating> org.apache.openjpa.persistence.ArgumentException:
The id class specified by type "class com.mycompany.book.Page" does not match the primary
key fields of the class.  Make sure your identity class has the same primary keys as your
persistent type, that the access types are the same, and if you are getting this error at
runtime, that you have your persistent class since last compiling your identity class.
FailedObject: book [java.lang.String]

any ideas?

Craig L Russell <Craig.Russell@Sun.COM> wrote: Hi Jeff,

The pattern you use for Book/Library is
> public class BookId implements Serializable {
>     private String name;
>     private String library;

The pattern you use for Page/Book is
> public class PageId implements Serializable {
>     private int number;
>     private BookId book;

Have you tried

> public class PageId implements Serializable {
>     private int number;
>     private String book;

Craig

On Apr 2, 2007, at 10:41 AM, jeff wrote:

> say i have Library, Book, and Page classes. a Library has many  
> Books, and a Book has many Pages. A Library's ID is it's name  
> (simple). A Book's ID is a composite of it's name and it's owning  
> Library's name (bidirectional relationship). A Page's ID is a  
> composite of it's number and it's owning Book's ID, a BookID.
>
> so, the PageId class starts like:
>
> public class PageId implements Serializable {
>     private int number;
>     private BookId book;
>
> the error i'm getting is at runtime ...
>
> <4|true|0.9.6-incubating>  
> org.apache.openjpa.persistence.ArgumentException: Field  
> "com.mycompany.book.Book.pages" declares  
> "com.mycompany.book.Page.book" as its mapped-by field, but this  
> field is not a direct relation.
>
> first, is what i'm trying to do even valid? i suspect it is not,  
> and the problem is that the fields of the ID class must be "simple"  
> types  (i believe the spec demands that). although, the error  
> message is a little confusing so i am not sure.
>
> it occurs to me that another way to achieve this would be to add  
> bookName and libraryName fields to the Page class, and add a  
> @PrePersist method that populates them by calling book.getName()  
> and book.getLibrary().getName(). but again this is messy because  
> that data is already in the table because of the bidirectional  
> relationship between the objects.
>
> as always, i'm open to "what are you an idiot?" responses if i am  
> just going about trying to define the Library, Book, Page  
> relationship in an obtuse manner.
>
> classes attached.
>
> The fish are biting.
> Get more visitors on your site using Yahoo! Search Marketing.
> package com.mycompany.book;
>
> import java.io.Serializable;
> import java.util.HashSet;
> import java.util.Set;
> import javax.persistence.CascadeType;
> import javax.persistence.Column;
> import javax.persistence.Entity;
> import javax.persistence.Id;
> import javax.persistence.IdClass;
> import javax.persistence.ManyToOne;
> import javax.persistence.OneToMany;
> import javax.xml.bind.annotation.XmlAttribute;
> import javax.xml.bind.annotation.XmlElement;
>
> @IdClass(com.mycompany.book.BookId.class)
> @Entity
> public class Book implements Serializable {
>     @Id
>     @Column(
>         name="BOOK_NAME",
>         nullable = false
>     )
>     @XmlAttribute (required = true)
>     private String name;
>
>     @OneToMany(
>         cascade = CascadeType.ALL,
>         mappedBy = "book"
>     )
>     @XmlElement (name = "page")
>     private Set
 pages = new HashSet
();
>
>     @Id
>     @Column(
>         nullable = false
>     )
>     @ManyToOne (
>       cascade = CascadeType.ALL
>     )
>     private Library library;
>
>     public String getName() {
>         return name;
>     }
>
>     public void setName(String name) {
>         this.name = name;
>     }
>
>     public Page getPage(int n) {
>         for (Page p: pages) {
>             if (p.getNumber() == n) {
>                 return p;
>             }
>         }
>
>         return null;
>     }
>
>     public void putPage(Page p) {
>         p.setBook(this);
>         pages.add(p);
>     }
>
>     public boolean equals(Object o) {
>         if (!(o instanceof Book)) {
>             return false;
>         }
>
>         Book other = (Book)o;
>
>         if (!getName().equals(other.getName())) {
>             return false;
>         }
>
>         return true;
>     }
>
>     public int hashCode() {
>         return getName().hashCode();
>     }
>
>     public Library getLibrary() {
>         return library;
>     }
>
>     public void setLibrary(Library library) {
>         this.library = library;
>     }
>
> }
> package com.mycompany.book;
>
> import java.io.Serializable;
> import javax.xml.bind.annotation.XmlTransient;
>
> @XmlTransient
> public class BookId implements Serializable {
>     private String name;
>     private String library;
>
>
>     public boolean equals(Object o) {
>         if (!(o instanceof BookId)) {
>             return false;
>         }
>
>         BookId other = (BookId)o;
>
>         if (!(getName().equals(other.getName()))) {
>             return false;
>         }
>
>         if (!getLibrary().equals(other.getLibrary())) {
>             return false;
>         }
>
>         return true;
>     }
>
>     public int hashCode() {
>         return getName().hashCode() * getLibrary().hashCode();
>     }
>
>     public String getName() {
>         return name;
>     }
>
>     public void setName(String name) {
>         this.name = name;
>     }
>
>     public String getLibrary() {
>         return library;
>     }
>
>     public void setLibrary(String library) {
>         this.library = library;
>     }
> }
> package com.mycompany.book;
>
> import java.io.Serializable;
> import java.util.HashSet;
> import java.util.Set;
> import javax.persistence.CascadeType;
> import javax.persistence.Column;
> import javax.persistence.Entity;
> import javax.persistence.Id;
> import javax.persistence.OneToMany;
> import javax.xml.bind.annotation.XmlAttribute;
> import javax.xml.bind.annotation.XmlElement;
> import javax.xml.bind.annotation.XmlRootElement;
>
> @Entity
> @XmlRootElement
> public class Library implements Serializable {
>     @Id
>     @Column(
>         name="LIBRARY_NAME",
>         nullable = false
>     )
>     @XmlAttribute (name = "name", required = true)
>     private String name;
>
>     @OneToMany(
>         cascade = CascadeType.ALL,
>         mappedBy = "library"
>     )
>     @XmlElement (name = "book")
>     private Set books = new HashSet();
>
>     public String getName() {
>         return name;
>     }
>
>     public void setName(String name) {
>         this.name = name;
>     }
>
>     public Book getBook(String name) {
>         for (Book b: books) {
>             if (b.getName().equals(name)) {
>                 return b;
>             }
>         }
>
>         return null;
>     }
>
>     public void putBook(Book book) {
>         book.setLibrary(this);
>         books.add(book);
>     }
>
>     public boolean equals(Object o) {
>         if (!(o instanceof Library)) {
>             return false;
>         }
>
>         Library other = (Library)o;
>
>         if (!getName().equals(other.getName())) {
>             return false;
>         }
>
>         return true;
>     }
>
>     public int hashCode() {
>         return getName().hashCode();
>     }
>
> }
> package com.mycompany.book;
>
> import java.io.Serializable;
> import javax.persistence.CascadeType;
> import javax.persistence.Column;
> import javax.persistence.Entity;
> import javax.persistence.Id;
> import javax.persistence.IdClass;
> import javax.persistence.ManyToOne;
> import javax.xml.bind.annotation.XmlAttribute;
>
> @IdClass(com.mycompany.book.PageId.class)
> @Entity
> public class Page implements Serializable {
>     @Id
>     @Column(
>         name="PAGE_NUMBER",
>         nullable = false
>     )
>     @XmlAttribute
>     private int number;
>
>     @Id
>     @Column(
>         nullable = false
>     )
>     @ManyToOne (
>       cascade = CascadeType.ALL
>     )
>     private Book book;
>
>     public int getNumber() {
>         return number;
>     }
>
>     public void setNumber(int number) {
>         this.number = number;
>     }
>
>     public Book getBook() {
>         return book;
>     }
>
>     public void setBook(Book book) {
>         this.book = book;
>     }
> }
> package com.mycompany.book;
>
> import java.io.Serializable;
> import javax.xml.bind.annotation.XmlTransient;
>
> @XmlTransient
> public class PageId implements Serializable {
>     private int number;
>     private BookId book;
>
>     public int getNumber() {
>         return number;
>     }
>
>     public void setNumber(int number) {
>         this.number = number;
>     }
>
>     public boolean equals(Object o) {
>         if (!(o instanceof PageId)) {
>             return false;
>         }
>
>         PageId other = (PageId)o;
>
>         if (!(getNumber() == other.getNumber())) {
>             return false;
>         }
>
>         if (!getBook().equals(other.getBook())) {
>             return false;
>         }
>
>         return true;
>     }
>
>     public int hashCode() {
>         return number * getBook().hashCode();
>     }
>
>     public BookId getBook() {
>         return book;
>     }
>
>     public void setBook(BookId book) {
>         this.book = book;
>     }
> }

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!





 
---------------------------------
Don't pick lemons.
See all the new 2007 cars at Yahoo! Autos.
Mime
  • Unnamed multipart/alternative (inline, 8-Bit, 0 bytes)
View raw message