Database: Removing or updating an item = OptimisticLockException

Discussion in 'Plugin Development' started by AbdulAbdalla, Sep 20, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    AbdulAbdalla

    Hi all,

    im using the bukkit database interface and i have problems deleting an item. Everytime i call the delete() or the update() function it crashes with the following stack trace:
    Code:
    01:49:44 [SCHWERWIEGEND] null
    org.bukkit.command.CommandException: Unhandled exception executing command 'home
    ' in plugin Crafthook v1.2
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:41)
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:16
    3)
            at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:3
    53)
            at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.
    java:755)
            at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:720)
    
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:713)
            at net.minecraft.server.Packet3Chat.a(Packet3Chat.java:33)
            at net.minecraft.server.NetworkManager.b(NetworkManager.java:226)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:91)
            at org.getspout.spout.SpoutNetServerHandler.a(SpoutNetServerHandler.java
    :500)
            at net.minecraft.server.NetworkListenThread.a(SourceFile:108)
            at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:464)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:374)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:417)
    Caused by: javax.persistence.OptimisticLockException: Data has changed. updated
    [0] rows sql[delete from home where id=? and owner=? and world=? and x=? and y=?
     and z=? and pitch=? and yaw=?] bind[null]
            at com.avaje.ebeaninternal.server.persist.dml.DmlHandler.checkRowCount(D
    mlHandler.java:123)
            at com.avaje.ebeaninternal.server.persist.dml.DeleteHandler.execute(Dele
    teHandler.java:81)
            at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(D
    mlBeanPersister.java:105)
            at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.delete(Dm
    lBeanPersister.java:67)
            at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeD
    eleteBean(DefaultPersistExecute.java:128)
            at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(Per
    sistRequestBean.java:535)
            at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeOrQueue
    (PersistRequestBean.java:557)
            at com.avaje.ebeaninternal.server.persist.DefaultPersister.delete(Defaul
    tPersister.java:654)
            at com.avaje.ebeaninternal.server.persist.DefaultPersister.delete(Defaul
    tPersister.java:464)
            at com.avaje.ebeaninternal.server.core.DefaultServer.delete(DefaultServe
    r.java:1831)
            at com.avaje.ebeaninternal.server.core.DefaultServer.delete(DefaultServe
    r.java:1821)
            at me.zacherl.crafthook.HomeCommandHandler.commandHomeUnset(HomeCommandH
    andler.java:105)
            at me.zacherl.crafthook.HomeCommandHandler.onCommand(HomeCommandHandler.
    java:124)
            at me.zacherl.crafthook.commands.SubCommandArgument.checkArgument(SubCom
    mandArgument.java:72)
            at me.zacherl.crafthook.commands.CommandItem.parseCommandLine(CommandIte
    m.java:99)
            at me.zacherl.crafthook.commands.CommandParser.parseCommandLine(CommandP
    arser.java:21)
            at me.zacherl.crafthook.Crafthook.onCommand(Crafthook.java:330)
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:39)
            ... 13 more
    It works with all my other database classes, but not with this one. I guess it could be a problem with the double and float values.

    Code:
    @Entity()
    @Table(name="home")
    @UniqueConstraint(columnNames = {"owner", "world"})
    public class DBHomeItem {
    
        @Id
        private int id;
        
        @NotNull
        private int owner;
    
        @Length(max=64)
        @NotEmpty
        @NotNull
        private String world;
        
        @NotNull
        private double x;
        
        @NotNull
        private double y;
        
        @NotNull
        private double z;
        
        @NotNull
        private float pitch;
        
        @NotNull
        private float yaw;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getOwner() {
            return owner;
        }
    
        public void setOwner(int owner) {
            this.owner = owner;
        }
    
        public String getWorld() {
            return world;
        }
    
        public void setWorld(String world) {
            this.world = world;
        }
    
        public double getX() {
            return x;
        }
    
        public void setX(double x) {
            this.x = x;
        }
    
        public double getY() {
            return y;
        }
    
        public void setY(double y) {
            this.y = y;
        }
    
        public double getZ() {
            return z;
        }
    
        public void setZ(double z) {
            this.z = z;
        }
    
        public float getPitch() {
            return pitch;
        }
    
        public void setPitch(float pitch) {
            this.pitch = pitch;
        }
    
        public float getYaw() {
            return yaw;
        }
    
        public void setYaw(float yaw) {
            this.yaw = yaw;
        }
        
    }
    push

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 19, 2016
  2. Offline

    masteroftime

    Optimistic concurrency is a method which assumes that multiple transactions can run at the same time without interfering. Therefore the transactions are executed and just before they are commited they check if another transaction interfered.

    And that is the problem in your case. Some other thread seems to access the data you want to modify at the same time. If you put your update/delete method in an asynchronous task change it to a synchronous. You can also try to change the concurrency control of your DB but don't ask me how to do that
     
  3. Offline

    AbdulAbdalla

    Thanks for your answer. Im performing the update / delete method directly in the onPlayerChat() event. Its working for all the other database structs but not for this one.

    But i will try it with the sync task and i will search for periodical read / write calls in the other threads.
     
  4. Offline

    AbdulAbdalla

    Ther problem is there again.

    If i use floats in my entity, it fails everytime i try to update or delete a row. If i use only doubles it works as it should until i restart the server.
    Reading and deleting is still possible, but updating gives me the old OptimisticLockException.

    Edit: And im not accessing the data from an other thread then the main thread.
     
Thread Status:
Not open for further replies.

Share This Page