Hibernate: Como salvar uma lista de endereços de um User no db?

Depois de um debate nesse tópico, fui convencido pelos argumentos técnicos expostos lá a estudar o Hibernate.

Me deparei com o seguinte problema: Preciso persistir no banco uma lista de objetos da minha entidade, por exemplo, um Usuário possui um conjunto de Endereços, algo assim:

public User {

    (...)

     private Set<Address> addresses;

     (...)
}

Fui direcionado para a documentação do Hibernate: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/collections.html#collections-ofvalues

Basicamente precisa fazer algo assim:

@Entity
public class User {
   [...]
   public String getLastname() { ...}

   @ElementCollection
   @CollectionTable(name="Addresses", joinColumns=@JoinColumn(name="user_id"))
   @AttributeOverrides({
      @AttributeOverride(name="street1", column=@Column(name="fld_street"))
   })
   public Set<Address> getAddresses() { ... } 
}

@Embeddable
public class Address {
   public String getStreet1() {...}
   [...]

Olhando assim rapidamente não entendi muito bem o que essas annotations significam. Mas deve ser alguma coisa simples que eu não estou capitando.

Alguém poderia explicar qual tipo de programação/lógica está sendo feita com as anotações acima?

O Hibernate é muito simples, logo eu devo estar com alguma dificuldade para entender essas anotações.

Eu faço dessa maneira os meus mapeamentos de listas.


public class Endereco {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	private String logradouro;
	
	private String complemento;
	
	private String bairro;
	
	private String cep;
	
	//no caso do mapeamento bidirecional.
	@ManyToOne
	@JoinColumn(name = "id_pessoa")
	private Pessoa pessoa;
	
	//gets e sets

}

@Entity
public class Pessoa {
	
	@Id
	@GeneratedValue
	private Integer id;
	
	private String nome;
	
	private String idade;
	
	/*
	 * mappedBy, usa se para fazer relacionamento bidirecional, portanto nesse caso e necessario ter um atributo
	 * com o mesmo nome do mapeamento (no caso 'pessoa') na entidade Endereco.
	 * 
	 * Caso prefira que o mapeamento seja unidirecional, é só retirar a anotação mappedBy que o hibernate
	 * cria uma tabela para gerenciar os endereços de uma pessoa
	 */
	@OneToMany(targetEntity = Endereco.class, fetch = FetchType.LAZY, mappedBy = "pessoa")
	@Cascade(CascadeType.ALL)
	private List<Endereco> enderecos;
	
	//gets e sets

}

se você tiver a anotação @Cascade(CascadeType.ALL), quando quizer persistir, é só fazer o save da entidade Pessoa que a lista sera persistida junto.