Relacionamento de Entidade no Google App Engine

2 respostas
danieldestro

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.

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
}
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
}
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);

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.

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
	
	// ...
}

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?

2 Respostas

Edufa

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.

danieldestro

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.

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
}
public Product findProduct(long id) {
		Product prod = findEntityById(Product.class, id);
		ProductGroup group = findEntityById(ProductGroup.class, prod.getIdGroup());
		prod.setGroup(group);
		return prod;
	}
Criado 30 de março de 2011
Ultima resposta 30 de mar. de 2011
Respostas 2
Participantes 2