Patrick Linskey <[EMAIL PROTECTED]> wrote: > my ID class has a book field, and
getters and setters for it
> to match Page's book field. i wonder about the last line
> where it says "java.lang.String". that seems odd.
Can you post your Book and Page classes and the Page's IdClass?
attached. i keep trying to attach the entire project as a zip, but apache's
spam filter keeps dropping it. let me know i could send to you directly.
> so, regardless, even if that did work, correct me if i am
> wrong, but it'd be a really bad idea to depend on openjpa
> specifics, because my app doesn't get to choose the JPA
> implementation, it has to use whatever the java ee container
> gives it ... right?
No -- a Java EE 5 container *must* allow you to specify your persistence
provider. Whatever you put in the
element in the
persistence.xml must be obeyed. Only if you do not specify a
element can the implementation can choose whatever it wants to use.
yes, duh. sorry.
Correct.
> so, assuming i do need to accomplish this, is there a best
> practice? as i mentioned, what i did to make it work was make
> the Page's composite ID incorporate the Book's ID by adding a
> "derived" bookName field to Page, like ...
You could add a private bookName field that has no external mutators or
accessors, and create a @PreStore callback that copies the value from
the related Book into the field. That would do a decent job of isolating
the artifact from the rest of your app.
yes, that works.
---------------------------------
Finding fabulous fares is fun.
Let Yahoo! FareChase search your favorite travel sites to find flight and hotel
bargains.
package com.mycompany.book;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Book implements Serializable {
@Id
@Column(
name="BOOK_NAME",
nullable = false
)
private String name;
@OneToMany(
cascade = CascadeType.ALL,
mappedBy = "book"
)
private List<Page> pages = new ArrayList<Page>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Page> getPages() {
return pages;
}
public void setPages(List<Page> pages) {
this.pages = pages;
}
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();
}
}
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.persistence.PrePersist;
@IdClass(com.mycompany.book.PageId.class)
@Entity
public class Page implements Serializable {
@Id
@Column(
name="PAGE_NUMBER",
nullable = false
)
private int number;
@Column(
nullable = false
)
@ManyToOne (
cascade = CascadeType.ALL
)
private Book book;
@Id
private String bookName;
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;
}
@PrePersist
protected void setBookName() {
bookName = getBook().getName();
}
}
package com.mycompany.book;
public class PageId {
private int number;
private String bookName;
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 (!getBookName().equals(other.getBookName())) {
return false;
}
return true;
}
public int hashCode() {
return number * getBookName().hashCode();
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}