Java 处理删除处理中的临时实体。无法删除实体[解决]
我的问题是,当我使用此代码删除Java 处理删除处理中的临时实体。无法删除实体[解决],java,database,spring,hibernate,jpa,Java,Database,Spring,Hibernate,Jpa,我的问题是,当我使用此代码删除Ship实体时,我会收到此消息 2017年3月8日13:01:36.504信息[http-nio-8080-exec-1]org.hibernate.event.internal.DefaultDeleteEventListener.DeleteTransiententy HHH000114:在删除处理中处理临时实体 但是在提交之后,我的实体仍然存在于数据库中 我用 弹簧4.2.1.释放 Hibernate 4.3.5.1最终版本 Mysql 5.1.30 代码:
Ship
实体时,我会收到此消息
2017年3月8日13:01:36.504信息[http-nio-8080-exec-1]org.hibernate.event.internal.DefaultDeleteEventListener.DeleteTransiententy HHH000114:在删除处理中处理临时实体
但是在提交之后,我的实体仍然存在于数据库中
我用
弹簧4.2.1.释放
Hibernate 4.3.5.1最终版本
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());
}
移除该船并向玩家添加该船的金币:
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在回答中所说的那样。我通过合并更改新船()
然后,我将忘记告诉您有关播放器的内容,如下所示:
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();
}
...
}
公共类播放器扩展了AbstractPlayer{
...
@凌驾
@OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.ALL},targetEntity=Ship.class,mappedBy=“player”)
公共集getShips(){
返回super.getShips();
}
...
}
当存在'fetch=FetchType.EAGER'时,一对多
就是问题所在
从这两个选项中求解一个:
将fetch更改为“lazy”,因为我没有这样做
在删除managedShip.getPlayer().getShips().remove(managedShip)之前添加此项代码>等于parentEntity.collection.remove(childEntity)
与我一样
在delete方法中,您应该在执行删除操作之前执行合并。我不知道为什么要创建Ship class的新实例,我认为可以省略:
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);
}
谢谢你的回答。在我做了你想做的事情之后,它会起作用的!伟大的很高兴我能帮上忙如果我合并了飞船,然后它被添加到数据库中,然后我删除了managedShip,所以总体上我什么都没做。我不能在没有合并的情况下获取托管对象吗?