GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Problema com mapeamento JPA + Hibernate

java
hibernate
jpa
Tags: #<Tag:0x00007f815a87bb20> #<Tag:0x00007f815a87b8c8> #<Tag:0x00007f815a87b620>

#1

Estou desenvolvendo um jogo de cartas e preciso persistir as classes JOGADOR, MAO (que contém as cartas na mão do jogador) e DECK (baralho do jogador).

@Entity

public class Jogador implements Serializable {

public enum FaseJogo {
    SELECAO, COMBATE, ESPERA;
}

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String login;
private int hp;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private FaseJogo fase;
@Embedded
private Deck deck;
@Embedded
private Mao mao;
@Embedded
private Campo campo;
private int turno;

public Jogador() {

}

public Jogador(String login) {
    this.login = login;
    this.turno = 0;
    this.fase = FaseJogo.SELECAO;
    this.hp = Comuns.MAXIMA_VIDA;
    this.deck = new Deck();
    this.mao = new Mao();
    this.campo = new Campo();
    this.atualizaMao();
}

public void atualizaMao() {
    while (this.mao.getCartas().size() < Comuns.MAXIMA_MAO) {
        Carta carta = this.deck.getCartas().get(this.deck.getCartas().size() - 1);
        carta.setEstadoCarta(Carta.EstadoCarta.MAO);
        this.mao.getCartas().add(carta);
        this.deck.getCartas().remove(this.deck.getCartas().size() - 1);
    }
}

public void reiniciar() {
    this.hp = Comuns.MAXIMA_VIDA;
    this.fase = FaseJogo.SELECAO;
    this.turno = 0;
    this.campo = new Campo();
    this.mao = new Mao();
    this.deck = new Deck();
    this.atualizaMao();
}

}

@Embeddable
public class Mao {

private List<Carta> cartas = new ArrayList<>();

@ManyToMany(cascade = CascadeType.ALL)
public List<Carta> getCartas() {
    return cartas;
}

public void setCartas(List<Carta> cartas) {
    this.cartas = cartas;
}

}

@Embeddable
public class Deck {

private List<Carta> cartas = new ArrayList<>();

public Deck() {
    this.cartas = gerarDeck(Comuns.MAXIMO_DECK);
}

@ElementCollection
public List<Carta> getCartas() {
    return cartas;
}

public void setCartas(List<Carta> cartas) {
    this.cartas = cartas;
}

private List<Carta> gerarDeck(int tamanho) {
    List<Carta> lista = new CartaDAO().getList();
    List<Carta> deck = new ArrayList<>();
    Carta carta;

    for (int i = 0; i < tamanho; i++) {
        carta = lista.get(new Random().nextInt(30));
        deck.add(carta);
    }

    return deck;
}

}

Quando tento persistir um objeto jogador é retornado o segundo erro:

Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: model.Carta
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:797)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:790)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:352)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:295)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:381)
at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:321)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:298)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
at org.hibernate.engine.internal.Cascade.cascadeComponent(Cascade.java:273)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:172)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:294)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:807)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:780)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:785)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
… 137 more

Alguém pode ajudar?


#2

Bom dia,

Esse erro quer dizer que vc está tentando atualizar um objeto que não está mais disponível na sessão do seu mecanismo de persistência.

Se é uma inserção simples, utilize o persist(objeto);
Se é uma atualização, utilize o find(objeto), mude o parâmetro e depois faça commit;