users@glassfish.java.net

Re: Entity beans, persistence and CascadeType.

From: Markus Fuchs <Markus.Fuchs_at_Sun.COM>
Date: Wed, 27 Jun 2007 15:08:31 -0700
Hi Ryan,

the Ids for both Author and Book are generated automatically by the Persistence Provider, as you specified SEQUENCE Id generation. Just specify CascadeType.PERSIST on the Author side of the relationship.

Thanks,

-- markus.

Ryan J wrote:
Hi,

I'm working with an application client and I'm running into an issue
when creating a new Entity and and persisting it via a remote interface.

The question I have is, when working with an application client and
detached Entity beans, how can I update the @Id field of child Entity
beans that are persisted via cascading?


Here's a stripped down example of how my entity beans would be set up
using a simple one to many (author to book) analogy:

  
@Entity
@Table(name = "AUTHOR")
public class Author implements Serializable {
	public static final String PROPERTYNAME_ID = "id";
	public static final String PROPERTYNAME_BOOKS = "books";

	private int id;
	private Collection<Book> books;

	public Author() {
		this.id = -1;
		this.books = new ArrayList<Book>();
	}

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@OneToMany(fetch = FetchType.EAGER, mappedBy = Book.PROPERTYNAME_AUTHOR)
	public Collection<Book> getBooks() {
		return books;
	}

	public void setBooks(Collection<Book> books) {
		this.books = books;
	}
}

@Entity
@Table(name = "BOOK")
public class Book implements Serializable {
	public static final String PROPERTYNAME_ID = "id";
	public static final String PROPERTYNAME_AUTHOR = "author";

	private int id;
	private Author author;

	public Book() {
		this.id = -1;
		this.author = new Author();
	}

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@ManyToOne
		@JoinColumn(name = "AUTHOR_ID")
	public Author getAuthor() {
		return author;
	}

	public void setAuthor(Author author) {
		this.author = author;
	}
}
    

When a new 'Author' is created with multiple 'Book'(s) I try to persist
using an approach that would be similar to the following
(EntitySaverRemote would be a remote interface that uses a
PersistenceContext):

Author a = new Author();
Book b1 = new Book();
Book b2 = new Book();

b1.setAuthor(a);
b2.setAuthor(a);

a.getBooks().add(b1);
a.getBooks().add(b2);

a.setId(EntitySaverRemote.saveAuthor(a));
b1.setId(EntitySaverRemote.saveBook(b1));
b2.setId(EntitySaverRemote.saveBook(b2));

Now, this is where I run into problems.  I get the following exception:

  
Caused by: java.rmi.RemoteException: null; nested exception is: 
 java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [Author.toString() would be here] (0 items).
    

I can add CascadeType.PERSIST to the Author side of the relationship,
but then I'm not sure how I would set the id of the newly created Book
objects on the client side.

Any suggestions (or suggested reading)?

Ryan

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net