Para inicializar ou não inicializar os mapeamentos de relacionamento do JPA?

Em uma ou várias associações JPA, é considerada uma prática recomendada inicializar relacionamentos para collections vazias? Por exemplo.

@Entity public class Order { @Id private Integer id; // should the line items be initialized with an empty array list or not? @OneToMany(mappedBy="order") List lineItems = new ArrayList(); } 

No exemplo acima, é melhor definir lineItems com um valor padrão de um ArrayList vazio ou não? Quais são os prós e contras?

O próprio JPA não se importa se a coleção é inicializada ou não. Ao recuperar um Pedido do database com o JPA, o JPA sempre retornará um Pedido com uma lista não nula de OrderLines.

Por que: porque um Pedido pode ter 0, 1 ou N linhas, e isso é melhor modelado com uma coleção vazia, de tamanho único ou tamanho N. Se a coleção fosse nula, você teria que verificar isso em todos os lugares no código. Por exemplo, esse loop simples causaria um NullPointerException se a lista fosse nula:

 for (OrderLine line : order.getLines()) { ... } 

Portanto, é melhor torná-lo invariante sempre tendo uma coleção não nula, mesmo para instâncias recém-criadas da entidade. Isso faz com que o código de produção crie novas encomendas mais seguras e limpas. Isso também faz com que os testes de sua unidade, usando instâncias de Pedidos não provenientes do database, sejam mais seguros e limpos.

Eu também recomendaria usar collections imutáveis ​​de goiaba, por exemplo,

 import com.google.common.collect.ImmutableList; // ... @OneToMany(mappedBy="order") List lineItems = ImmutableList.of(); 

Esse idioma nunca cria uma nova lista vazia, mas reutiliza uma única instância representando uma lista vazia (o tipo não importa). Esta é uma prática muito comum de linguagens de programação funcionais (o Scala também faz isso) e reduz a zero a sobrecarga de ter objects vazios em vez de valores nulos, fazendo com que qualquer argumento de eficiência seja contrário ao idiom.