Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Programadores expereiente

Vocês programadores, eu não gosto muito de usar o cascade, mais não tive como fugir nessa situação, gosto de treinar bastante os códigos que vou aprendendo com O CDI agora estou vendo ele. mais isso não tem nada a ver com a dúvida, como disse não gosto de usar cascade, e taria certo o meu metodo de atualizar?

@Transacional
    public void salvar() {
        if (produto.getCodigo() == null) {
            fabricante.setProduto(produto);
            produtoDao.salvar(produto, fabricante);
        } else {
            produtoDao.alterar(produto, fabricante);
        }
        this.produto = new Produto();
        this.fabricante = new Fabricante();
    }
public void alterar(Produto produto, Fabricante fabricante) {
        manager.merge(produto);
        manager.merge(fabricante);
    }
public Redirecionador carregar(Produto produto) {
        this.produto = produto;
        for (int i = 0; i < produto.getFabricantes().size(); i++) {
            this.fabricante = produto.getFabricantes().get(i);
        }
        return new Redirecionador("produto");
    }
8 respostas

Fala, Alisson!

Esse teu método alterar tá muito procedural. Como você criou off topic, não sei qual curso você está fazendo. Em todo caso, parece estar usando CDI, pela anotação @Transacional, e controlando as transações. Se for esse o caso, lembre-se de fazer o método igual aos demais. Se você está no DAO, acesse diretamente o EntityManager. Se está em uma camada superior (regra de negócio ou bean), acesse os métodos do DAO para fazer o merge. Se você está controlando a transação, o método alterar também precisa estar anotado com @Transacional.

Qualquer coisa, posta aí...

Abraço.

Manoel quanto tempo kkkk, pois então estou usando CDI. o codigo alterar está dentro da meu pacote dao, não especifiquei mais só o metodo alterar que está dentro do meu dao, os outros 2 estão dentro do meu bean

solução!

Tava de férias, Alisson! Férias de trabalho, faculdade, Alura... kkkkk. Preciso de um descanso vez em quando... hehe. Mas tô de volta...

Então...

Lembra do post anterior sobre cascade? Mesma coisa aqui:

public void alterar(Produto produto, Fabricante fabricante) {
    manager.merge(produto);
    manager.merge(fabricante);
}

Remove o pai, que ele remove o filho... Se o objeto produto tem um objeto fabricante, você pode acessá-lo direto, através do:

produto.setFabricante()

Na JPA 2.0, você ainda tem o orphanRemoval para as anotações @OneToOne e @OneToMany:

@Entity
class Pessoa {
    // outros atributos
    @OneToOne(orphanRemoval=true)
    private Endereco endereco;
}

Removendo o objeto do tipo Pessoa, a JPA removerá o objeto Endereco também. Similar ao cascade, mas usando apenas JPA e apenas para as duas anotações citadas.

Abraço.

Ta certo mano, Manoel poderia me falar uma coisa que não tem muito haver com o assunto da minha duvida? Assinei a Alura e confesso que não sabia nada de programação, hojê em dia apreendi umas coisas, Mais igual vejo você, você manda muito bem, há quanto tempo você ja programa? No começo foi dificil pra você também? Já teve muitas duvidas? E essa anotação que você me falo, só serve com anotaçao oneToMany e oneToOne? Você me deu o exemplo colocando ela no endereco, isso que dizer se eu remover a pessoa automaticamente ira remover o endereco dessa pessoa? Poderia ser assim?No caso tivesse uma lista poderia assim?

public Class Pessoa {

@OneToMany(orphanRemoval=true) // esta correto?
private Endereco enderecos = new ArrayList<>();
}

Aqui essa anotação quer se referir se eu remover uma pessoa, ira remover o meus enderecos dessa pessoa?

Alisson, programo há uns 8 anos mas, focado em Java e os frameworks dele, há uns 4 a 5 anos. O começo foi muito complicado, porque aprendi o paradigma estruturado na universidade (C, Pascal, Assembly e Portugol). É bem difícil aprender estruturado e, depois, esquecer tudo pra aprender o orientado a objetos... melhor começar no OO... hehe. Além disso, não tinha alguém que sacasse bastante pra eu poder pegar conhecimento, tive que aprender "na tora". Depois fiz uns cursos da Caelum, deu uma clareada, mas só no dia a dia mesmo é que a gente aprende. Tive muito mais dúvidas que você... kkkkkkk. Não tinha esses vídeos mastigadinhos explicando tudo... hehe. Mas você vem evoluindo, cara, dá pra perceber tua evolução através da evolução das tuas dúvidas... estão cada vez mais específicas, buscando cada vez mais os detalhes, isso é bom! Esse é o caminho!

A diferença entre o orphanRemoval e o cascade=CascadeType.REMOVE é assim:

Se você setar o endereço pra null no objeto pessoa, o orphanRemoval vai remover os endereços automaticamente (da tabela do banco de dados), pois perdem a referência do objeto pai. Ele é mais agressivo.

Se você setar o endereço pra null no objeto pessoa, o cascade=CascadeType.REMOVE não vai remover os endereços (eles vão continuar na tabela, como lixo), porque nenhuma ação de remoção foi executada (um entityManager.remove(objeto), por exemplo).

Então, nesse último exemplo seu, se remover a pessoa, os endereços também são removidos junto. Bem melhor que fazer aquela gambiarra procedural de remover primeiro os endereços na mão e, depois, o objeto pessoa, né?! hehe

há então ta explicado o porque você manda bem kkkkk. Um dia chego ao seu nivel kkk. Ainda mais com vocês me ajudando aqui :), cara obrigado por todas as duvidas, suas explicações são excelentes, parabéns e obrigado por passar um pouco do seu conhecimento. Um grande abraço

kkkkk. Logo logo você estará fera! Por nada, amigo. Qualquer coisa, só postar. Se eu souber, te explico. :)

Forte abraço.

Certo meu amigo! agora só para matar mesmo o assunto de anotações, o hibernate é utilizado para gerar tabelas no banco de dados e suas colunas né? sem precisar ter que gerar select pra adicionar e essas coisas correto? o jpa é pra que? serve de anotaçoes? mais hibernate tbem tem anotação né?