在删除处理中处理瞬态实体.实体不被删除[solve]



我的问题是当我使用此代码删除Ship实体时,我会收到此消息

08-MAR-2017 13:01:36.504信息[http-nio-8080-exec-1] org.hibernate.event.Event.Internal.defaultDeleteeventListener.deteretransententity hhhhh000114 hhhhh000114:在删除处理

/blockquote>

提交后,我的实体仍然存在于数据库中

我使用 Spring 4.2.1.RELEASE Hibernate 4.3.5.Final Mysql 5.1.30

代码:

船:

@JsonIgnoreProperties({"player", "game", "version"})
@Entity
@Table( name = "ship_tbl",
    uniqueConstraints = { @UniqueConstraint( columnNames = { "ship_name" , "game_id"}, name = "UK_ship_player") } )
public class Ship extends AbstractShip {
private Player player;
private Game game;
private Long version;
@Version
@Column(name = "ship_version")
public Long getVersion() {
    return version;
}
public void setVersion(Long version) {
    this.version = version;
}
@Override
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name = "ship_id")
public Long getId() {
    return super.getId();
}
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Player.class)
@JoinColumn(name="player_id", nullable = false)
public Player getPlayer() {
    return player;
}
@Override
@OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, targetEntity = Cargo.class)
@JoinColumn(name="cargo_id", nullable = false)
public AbstractCargo getCargo() {
    return super.getCargo();
}
@Override
@OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, targetEntity = ShipWay.class)
@JoinColumn(name="shipway_id", nullable = false)
public AbstractShipWay getShipWay() {
    return super.getShipWay();
}
@Override
@ManyToOne(fetch = FetchType.EAGER, targetEntity = ShipKind.class)
@JoinColumn(name="shipkind_id", nullable = false)
public AbstractShipKind getShipKind() {
    return super.getShipKind();
}
@ManyToOne(fetch = FetchType.LAZY, targetEntity = Game.class)
@JoinColumn(name = "game_id", nullable = false)
public Game getGame() {
    return game;
}
public void setGame(Game game) {
    this.game = game;
}
@Override
@Column(name = "ship_name", nullable = false)
public String getName() {
    return super.getName();
}
public void setPlayer(Player player) {
    this.player = player;
}
public Ship(Long id, String name, AbstractCargo cargo, AbstractShipKind shipKind, AbstractShipWay shipWay, Player player, Game game) {
    super(id, name, cargo, shipKind, shipWay);
    this.player = player;
    this.game = game;
}
public Ship(String name, AbstractCargo cargo, AbstractShipKind shipKind,AbstractShipWay shipWay) {
    this(null, name, cargo, shipKind, shipWay,null,null);
}
public Ship() {
    this(null,null,null,null);
}
}

dao

此卸下船:

private void removeShip(Session session, Ship ship) {
    Ship s = new Ship();
    s.setId(ship.getId());
    session.delete(s);
}

卸下船并将其添加到玩家是船的黄金:

private void sellShip(Session session, Player player, Ship ship) throws ShipNotExistsException {
    removeShip(session, ship);
    updatePlayerGold(session, player, ship.getShipKind().sellShipAmount());
}

进行交易加返回int错误:

@Override
public int sellShip(Player player, Ship ship) {
    int error;
    Session session = null;
    Transaction transaction = null;
    try{
        session = openSession();
        transaction = session.beginTransaction();
        transaction.setTimeout(5);
        sellShip(session, player, ship);
        transaction.commit();
        error = Response.ERROR_NONE_ERRORS;
    }catch(RuntimeException e) {
        if(e instanceof ShipNotExistsException) {
            error = Response.ERROR_SHIP_NOT_EXISTS_OR_MATCH;
        } else {
            e.printStackTrace();
            //TODO add else if stament and else insetent this
            //already in transtaction
            error = Response.ERROR_ALREADY_IN_TRANSACTION;
        }
        //if(!(e instanceof LockAcquisitionException)) {
        try {
            transaction.rollback();
        } catch (RuntimeException re) {
            re.printStackTrace();
        }
        //}
        //throw e;
    }finally{
        if(session!=null){
            session.close();
        }
    }
    return error;
}

我在这个问题上解决了3个小时,我将感谢任何帮助或解释!

谢谢您的重新订阅。

解决方案:

正如@maciej Kowalski在答案中所说。我更改了新的船(),合并。

更多,我会忘记告诉您有关Player实体的信息:

public class Player extends AbstractPlayer {
...
@Override
@OneToMany(fetch = FetchType.EAGER,cascade = {CascadeType.ALL}, targetEntity = Ship.class, mappedBy = "player")
public Set<AbstractShip> getShips() {
    return super.getShips();
}
...
}

好吧, one-to-many是exsits'fetch = fetchype.eager'

时的问题

从这两个选项中解决一个:

  1. 就像我没有那样,更改为"懒惰"。
  2. 在删除 managedShip.getPlayer().getShips().remove(managedShip);等于 parentEntity.collection.remove(childEntity)之前,请

在删除方法中,您应该在执行删除操作之前执行合并。我不确定为什么要创建一个新的船舶类实例,我认为可以省略:

private void removeShip(Session session, Ship ship) {
    Ship managedShip = session.merge(ship);
    session.delete(managedShip);
}

在删除实体之前,必须确保其由持久提供商进行管理。

我认为您需要在方法中更改陈述顺序:

private void sellShip(Session session, Player player, Ship ship) throws ShipNotExistsException {
    updatePlayerGold(session, player, ship.getShipKind().sellShipAmount());
    removeShip(session, ship);
}

最新更新