Relacionamento de Entidade no Google App Engine

Estou meio que apanhando para fazer simples relacionamentos de entidades na minha aplicação com JPA para rodar no Google App Engine (GAE).

Um simples caso de relacionamento 1-N está virando um inferno.

Descobri que não posso usar chaves do tipo Long para classes relacionadas, então passei a usar Key.

[code]package my.model;

@Entity
public class Product implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

private String name;
private String description;
private Double price;

@ManyToOne(cascade=CascadeType.MERGE)
private ProductGroup group;

public Product() {
}

public Long getId() {
	return (this.key==null) ? null : this.key.getId();
}

public void setId(Long id) {
	if( id != null ) {
		this.key = KeyFactory.createKey(getClass().getSimpleName(), id);
	}
}

// outros get / set

}[/code]

[code]package my.model;

@Entity
public class ProductGroup implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

private String name;

public ProductGroup() {
}

public Long getId() {
	return (this.key==null) ? null : this.key.getId();
}

public void setId(Long id) {
	if( id != null ) {
		this.key = KeyFactory.createKey(getClass().getSimpleName(), id);
	}
}

// outros get / set

}[/code]

[code]ProductGroup group = new ProductGroup();
group.setName(“Books”);
dao.persist(group);

Product prod = new Product();
prod.setName(“GUJ Book”);
prod.setPrice(99.99);
prod.setGroupd( group );
dao.persist(prod);[/code]

Porém, no caso acima tomei uma exceção que pede que eu crie o ProductGroup com um “parent” para o seu key, já que estou associando a um Product. Ou seja, o relacionamento, obrigatoriamente, tem de ser OWNED.

Uma coisa simples, fica difícil de se fazer.

Neste caso, estou pensando em abrir mão de usar relacionamentos entre objetos e usar as classes como simples estrutura de dados.

[code]package my.model;

@Entity
public class Product implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;

private String name;
private String description;
private Double price;

private Long idGroup; // talvez Key no lugar de Long

// ...

}[/code]

Terei de fazer “JOIN” e sumarização (sum, avg, etc) na mão. Me parece deselegante, do ponto de vista do design, mas, talvez, uma simples solução para não me matar a cada hora descobrindo as restrições do GAE com o seu BigTable / Datanucleus.

Alguém sugere uma outra solução viável?

Se serve de consolo eu tb tive estes mesmos problemas.

Como o domínio cresceu resolvi usar o AWS usando o free tier deles.

Mas pretendo voltar ao GAE qdo tiver mais tempo, se achar alguma solução posta aqui.

Simplesmente uso Long como id e não uso mais relacionamentos persistentes, só faço referência às “FKs”. E ai carrego na “mão” os objetos relacionados.

[code]public class Product implements Entity {

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@Transient
private ProductGroup group;

public ProductGroup getGroup() {
	return group;
}

public void setGroup(ProductGroup group) {
	this.group = group;
}

@Basic
public Long getIdGroup() {
	return (group==null) ? null : group.getId();
}

public void setIdGroup(Long id) {
	this.group = new ProductGroup();
	this.group.setId(id);
}

// mais gets e sets

}[/code]

public Product findProduct(long id) { Product prod = findEntityById(Product.class, id); ProductGroup group = findEntityById(ProductGroup.class, prod.getIdGroup()); prod.setGroup(group); return prod; }