Hibernate: StaleStateException

Status
Nicht offen für weitere Antworten.

KlinCh

Mitglied
Hi,
Ich hab wiedereinmal Probleme mit Hibernate.
Im Prinzip soll die Methode createUser() einfach nur einen neuen Player in die Datenbank speichern.
Dabei bekomme ich aber immer diese Exception, die ich mir nicht erklären kann, da ich ja gar nichts update???.
Java:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
        at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
        at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:24)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)
        at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
        at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at mySchool.core.Database.createUser(Database.java:78)

die Funktion createUser:
Java:
 public static Player getPlayer(String username, String password) {

        Session session = InitHibernate.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Query query = session.createQuery("select u from mySchool.gameObjects.Player as u where u.name=:username and u.password=:password");
        query.setString("username", username);
        query.setString("password", password);
        boolean b = true;

        Player player = null;
        if(query.list().size() >= 1){
            player = (Player) query.uniqueResult();
        }

        session.getTransaction().commit();
        return player;

       
        
    }
    public static void createUser(String username, String email, String password, Region region) throws UserDoesAlreadyExistException {

       
        if (getPlayer(username, password) == null) {
            Session session = InitHibernate.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            Player p = new Player();
            session.save(p);
            p.setName(username);
            p.setPassword(password);
            p.setEmail(email);
            p.setRegion(region);
          
            session.getTransaction().commit();
        } else {
            throw new UserDoesAlreadyExistException();
        }
    }

Wisst ihr wo der Fehler liegt?
Falls ihr noch mehr Code braucht, fragen oder einfach anonym das svn-repo checken:
myschool - Revision 74: /

Danke schonmal
 
S

SlaterB

Gast
es wird anscheinend ein Player-Objekt geupdated, welches keine Id hat, daher schlägt das Update fehl,

setze die Daten vor dem Save, dann ist später kein Update nötig,
oder prüfe nach, ob das Player-Objekt beim Save automatisch eine Id erhielt, falls diese überhaupt konfiguriert ist
 

KlinCh

Mitglied
Danke,

Also an einer fehlenden PlayerId liegt es nicht:
Java:
...
@Entity(name="TUSER")
@SequenceGenerator(sequenceName="tuser_id_seq", name="user_id")
public class Player implements Serializable{

    @Id
    @GeneratedValue(generator="user_id", strategy=GenerationType.AUTO)
    int id;
...

Aber mir ist noch etwas eingefallen, ich hab das p.setRegion(region) mal auskommentiert und siehe da es läuft reibungslos. :)

Ich schau erstmal selber, wenn ichs jetzt den Fehler nicht finde, dann meld ich mich nochmal.
 

KlinCh

Mitglied
Ok, ich kriegs doch nicht alleine hin :-(

also das mit Region ist so ne Sache also das Objekt, das createUser() bekommt ist statisch.
(alle Regionen kommen hardgecoded als statische Objekte vor)

Jetzt 2 Fragen:
1. Es müsste doch möglich sein diese abzuspeichern, oder?
2. Es funktioniert nicht, dass eine Hibernate-Entity eine Beziehung zu einem statischen Objekt hat, oder ?

aber:
ich hab probiert vor dem .save(p) noch ein .save(region) zu machen.
Hilft aber anscheinend auch nicht weiter.
 
S

SlaterB

Gast
habe ich nicht eindeutige Anweisungen gegeben?

p.setName(username);
p.setPassword(password);
p.setEmail(email);
p.setRegion(region);


VOR

session.save(p);


--------

außerdem/ alternativ nachschauen, ob p nach dem save() eine Id != 0 hat
 

KlinCh

Mitglied
Doch hast du.
Mein Code sieht ja auch so aus:
Java:
 public static void createUser(String username, String email, String password, Region region) throws UserDoesAlreadyExistException {

       
        if (getPlayer(username, password) == null) {
            Session session = InitHibernate.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            Player p = new Player();
            p.setName(username);
            p.setPassword(password);
            p.setEmail(email);
            p.setRegion(region);

            session.save(p);
            session.getTransaction().commit();
        } else {
            throw new UserDoesAlreadyExistException();
        }
    }
 
S

SlaterB

Gast
und gibt es noch eine Exception, die vom Anfang?

hat es was mit der Region zu tun, funktioniert das ganze, wenn du keine Region setzt, gar Region ganz aus dem Mapping entfernst?

wie sind Player und Region definiert/ gemappt?
 

KlinCh

Mitglied
Also die Exception bleibt die selbe,
wenn ich (wie oben beschrieben) die Region nicht setzte, dann gibt es kein Problem.

Ich poste jetzt mal den Quellcode von Player und Region:
Player:
Java:
@Entity(name="TUSER")
@SequenceGenerator(sequenceName="tuser_id_seq", name="user_id")
public class Player implements Serializable{

    @Id
    @GeneratedValue(generator="user_id", strategy=GenerationType.AUTO)
    int id;
    String name;
    String password;
    String email;
    String profile;

    @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    Building building = new Building();
    private double money = Configuration.getStartMoney();
    private long points = 0;
    private int roomForStudents =20;

//        @OneToMany
//    private Set<Staff> staff = new HashSet<Staff>();
        @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private Score score = new Score();

        @OneToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private Skill skill = new Skill();
//        @OneToMany(mappedBy="receiver")
//    private Set<Message> messages = new HashSet<Message>();

        @OneToMany(mappedBy="player", cascade=CascadeType.ALL)
    private Set<Calculation> calculations = new HashSet<Calculation>();

        @ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
    private Region region;

    /* alles für die ChaosEvents */
        @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private ChaosEvent currentChaosEvent = null;

        @Temporal(javax.persistence.TemporalType.DATE)
    private Date lastChaosEvent = new Date();

        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private Set<ChaosEvent> alreadyHappenedChaosEvents = new HashSet<ChaosEvent>();



        
     public Player() {
      
    }
und Region:
Java:
@Entity
@SequenceGenerator(name="region_id", sequenceName="region_id_seq")
public class Region implements Serializable{

    @Id
    @GeneratedValue(generator="region_id", strategy=GenerationType.AUTO)
    private int id;
    
    @Transient
    static public ArrayList<Region> allRegions = new ArrayList<Region>();

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private Set<Subject> subjects = new LinkedHashSet<Subject>();
    private String name;
    private double funds;   // Zuschüsse vom Staat
    private double securityFactor;

    public double getFunds() {
        return funds;
    }

    public void setFunds(double funds) {
        this.funds = funds;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSecurityFactor() {
        return securityFactor;
    }

    public void setSecurityFactor(double securityFactor) {
        this.securityFactor = securityFactor;
    }

    public Set<Subject> getSubjects() {
        return subjects;
    }



   @Transient
    public static Region BAWU = new Region("Baden-Württemberg", 1000.0, 1.5,
            new Subject("Geschichte", 6),
            new Subject("Sport", 3)
           );

   @Transient
    public static Region Frankfurt = new Region("Frankfurt", 100.0, 0.8,
    new Subject("Wirtschaft", 7),
    new Subject("Mathe", 4)
           );
...

    public Region () {
       
    }
    public Region(String name, double funds, double secFactor, Subject... someSubjects){
        allRegions.add(this);
        this.funds = funds;
        this.name = name;
        this.securityFactor = secFactor;
        for(Subject s : someSubjects){
            subjects.add(s);
        }
        
    }

Sorry, ist jetzt ein bisschen viel Code, aber ich weiss mir nicht anders zu helfen, als Leute hier im Forum zu nerven.
 
S

SlaterB

Gast
setze testweise nicht die statische alte Region, sondern lade über die Session das aktuelle Objekt zur fraglichen Id,
(zum xy. mal wie immer der Hinweis, von allen Objekten überhaupt mal die Id auszugeben ;) ) und speichere das aktuelle Objekt

-------

im Internet findet man zu der Exception hauptsächlich delete-Fehler


> @ManyToOne(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
> private Region region;

das Cascade wundert mich, die Region ist doch unabhängig von Player, existiert auch ohne diese?
durch das Cascade wurde die Region vielleicht irgendwann in der Datenbank gelöscht, ist gar nicht mehr bekannt, nur noch in der statischen Liste vorhanden?
wurden die Regionen überhaupt vorher gespeichert, haben sie eine Id?

das sind aber langsam sehr viele Vermutungen, ich glaube das ist aus der Ferne nicht mehr richtig effektiv
 

KlinCh

Mitglied
setze testweise nicht die statische alte Region, sondern lade über die Session das aktuelle Objekt zur fraglichen Id,

Yes, das wars !
Ich hab jetzt in meiner Database.java einen statischen Block eingefügt, der zuerst einmal alles was irgendwie statisch ist, in die datenbank speichert bzw. updated. Nun funktioniert es.

Das Cascading war natürlich blöd, hab ich jetzt auch weggemacht.

Danke, Danke, Danke.
 

KlinCh

Mitglied
Ok, jetzt das erstmalige Laden in die DB geht doch nicht ganz reibungslos.
Und ich hab wiedermal keine ahnung.
Meine Database.java sieht jetzt so aus:

Java:
public class Database {

    static boolean isInitializised = false;
    
    static {
        if(isInitializised == false){
            initialize();
        }
    }
    public static void initialize(){
        Logger logger = Logger.getLogger(Database.class.getName());
        logger.log(Level.INFO, "Initializising Database");
        isInitializised = true;
        Session session = InitHibernate.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        try{
            /* Läd alle Fächer in die Datenbank */
            logger.log(Level.INFO, "Loading all Subjects into DB");
            for(Subject s : Subject.allSubjects){
                logger.log(Level.INFO, "saveOrUpdate Subject :"+s.toString()+", ID: "+s.getId());
               session.update(s);
           }
           
            /* Läd alle Regionen in die Datenbank */
            logger.log(Level.INFO, "Loading all Regions into DB");
            for(Region r : Region.allRegions){
                session.saveOrUpdate(r);
                logger.log(Level.INFO, "saveOrUpdate Region :"+r.toString()+", ID: "+r.getId());
            }
            /* Läd alle ChaosEvents in die Datenbank */
            logger.log(Level.INFO, "Loading all ChaosEvetns into DB");
            for(ChaosEvent ce : ChaosEvent.allChaosEvents){
                session.saveOrUpdate(ce);
                logger.log(Level.INFO, "saveOrUpdate ChaosEvent :"+ce.toString()+", ID: "+ce.getId());
            }

            

            session.getTransaction().commit();
            logger.log(Level.INFO, "Initializising Database: successfull");

        } catch(HibernateException ex){
            session.getTransaction().rollback();
            ex.printStackTrace();
            logger.log(Level.WARNING, "Initializising Database: error");
        }
    }

    public static List<Region> getRegions(){
        Session s = InitHibernate.getSessionFactory().getCurrentSession();
        s.beginTransaction();
        Query q = s.createQuery("select r from mySchool.gameObjects.Region as r");
        List<Region> list = q.list();
        s.getTransaction().commit();
        return list;
    }

    /**
     *
     * @param username: String username
     * @param password: String password
     * @return the player from the database maybe <code>null</code>
     *
     */
    public static Player getPlayer(String username, String password) {

        Session session = InitHibernate.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Query query = session.createQuery("select u from mySchool.gameObjects.Player as u where u.name=:username and u.password=:password");
        query.setString("username", username);
        query.setString("password", password);
        boolean b = true;

        Player player = null;
        if(query.list().size() >= 1){
            player = (Player) query.uniqueResult();
        }

        session.getTransaction().commit();
        return player;

       
        
    }
    public static Player authentificate(String username, String password) throws WrongUserNameOrPasswordException{

        boolean isPlayer = false;
         Player player = getPlayer(username, password);
         isPlayer = player != null;
         Logger.getLogger(Database.class.getName())
                .log(Level.FINE, ("Authentifikation: "+username+" succesfull: "+isPlayer));
         if(isPlayer){
             return player;
         } else {
             throw new WrongUserNameOrPasswordException();
         }
    }


    public static void createUser(String username, String email, String password, Region region) throws UserDoesAlreadyExistException {

        
        if (getPlayer(username, password) == null) {
            Session session = InitHibernate.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            Player p = new Player();

            p.setName(username);
            p.setPassword(password);
            p.setEmail(email);
            p.setRegion(region);

            session.save(p);

             Logger.getLogger(Database.class.getName())
                .log(Level.FINE, ("User succesfully created: "+p.getId()+", "+p.getName()+", "+p.getEmail()));
             
            session.getTransaction().commit();
        } else {
            throw new UserDoesAlreadyExistException();
        }
    }
}

und die Exception ist wieder eine StaleException aber jetzt sieht das ein bisschen anders aus:
Code:
INFO: schema update complete
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: Loading all Subjects into DB
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Mathe, ID: 1
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Deutsch, ID: 2
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Französisch, ID: 3
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Englisch, ID: 4
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Sport, ID: 5
27.05.2009 16:13:27 mySchool.core.Database initialize
INFO: Loading all Regions into DB
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Region :Baden-Württemberg, ID: 453
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: Loading all ChaosEvetns into DB
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate ChaosEvent :Schlägerei, ID: 1
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate ChaosEvent :Mobbing in der 7a, ID: 2
27.05.2009 16:13:28 org.hibernate.util.JDBCExceptionReporter logExceptions
[B]WARNUNG:[/B] SQL Error: -1, SQLState: 23503
27.05.2009 16:13:28 org.hibernate.util.JDBCExceptionReporter logExceptions
SCHWERWIEGEND: INSERT in Tabelle 'REQUIREMENT' hat für Schlüssel (2) die Integritätsbedingung 'FK7912842313767E40' für Fremdschlüssel verletzt. Die Anweisung wurde zurückgesetzt.
27.05.2009 16:13:28 org.hibernate.event.def.AbstractFlushingEventListener performExecutions
[B]SCHWERWIEGEND: [/B]Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [mySchool.gameObjects.util.Requirement]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at mySchool.core.Database.initialize(Database.java:70)
        at mySchool.core.Database.<clinit>(Database.java:38)
        at mySchool.core.Test.main(Test.java:29)
Caused by: java.sql.SQLIntegrityConstraintViolationException: INSERT in Tabelle 'REQUIREMENT' hat für Schlüssel (2) die Integritätsbedingung 'FK7912842313767E40' für Fremdschlüssel verletzt. Die Anweisung wurde zurückgesetzt.
        at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
        at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2247)
        ... 13 more
Caused by: org.apache.derby.client.am.SqlException: INSERT in Tabelle 'REQUIREMENT' hat für Schlüssel (2) die Integritätsbedingung 'FK7912842313767E40' für Fremdschlüssel verletzt. Die Anweisung wurde zurückgesetzt.
        at org.apache.derby.client.am.Statement.completeExecute(Unknown Source)
        at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(Unknown Source)
        at org.apache.derby.client.net.NetStatementReply.readExecute(Unknown Source)
        at org.apache.derby.client.net.StatementReply.readExecute(Unknown Source)
        at org.apache.derby.client.net.NetPreparedStatement.readExecute_(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.readExecute(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.flowExecute(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.executeUpdateX(Unknown Source)
        ... 16 more
org.hibernate.exception.ConstraintViolationException: could not insert: [mySchool.gameObjects.util.Requirement]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at mySchool.core.Database.initialize(Database.java:70)
        at mySchool.core.Database.<clinit>(Database.java:38)
        at mySchool.core.Test.main(Test.java:29)
Caused by: java.sql.SQLIntegrityConstraintViolationException: INSERT in Tabelle 'REQUIREMENT' hat für Schlüssel (2) die Integritätsbedingung 'FK7912842313767E40' für Fremdschlüssel verletzt. Die Anweisung wurde zurückgesetzt.
        at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
        at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.executeUpdate(Unknown Source)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2247)
        ... 13 more
Caused by: org.apache.derby.client.am.SqlException: INSERT in Tabelle 'REQUIREMENT' hat für Schlüssel (2) die Integritätsbedingung 'FK7912842313767E40' für Fremdschlüssel verletzt. Die Anweisung wurde zurückgesetzt.
        at org.apache.derby.client.am.Statement.completeExecute(Unknown Source)
        at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(Unknown Source)
        at org.apache.derby.client.net.NetStatementReply.readExecute(Unknown Source)
        at org.apache.derby.client.net.StatementReply.readExecute(Unknown Source)
        at org.apache.derby.client.net.NetPreparedStatement.readExecute_(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.readExecute(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.flowExecute(Unknown Source)
        at org.apache.derby.client.am.PreparedStatement.executeUpdateX(Unknown Source)
        ... 16 more
27.05.2009 16:13:28 mySchool.core.Database initialize
WARNUNG: Initializising Database: error
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: Initializising Database
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: Loading all Subjects into DB
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Mathe, ID: 1
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Deutsch, ID: 2
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Französisch, ID: 3
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Englisch, ID: 4
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Subject :Sport, ID: 5
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: Loading all Regions into DB
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate Region :Baden-Württemberg, ID: 453
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: Loading all ChaosEvetns into DB
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate ChaosEvent :Schlägerei, ID: 1
27.05.2009 16:13:28 mySchool.core.Database initialize
INFO: saveOrUpdate ChaosEvent :Mobbing in der 7a, ID: 2
27.05.2009 16:13:28 org.hibernate.event.def.AbstractFlushingEventListener performExecutions
[B]SCHWERWIEGEND:[/B] Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
        at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
        at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:24)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)
        at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
        at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at mySchool.core.Database.initialize(Database.java:70)
        at mySchool.core.Test.main(Test.java:29)
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
        at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61)
        at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:24)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2403)
        at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
        at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at mySchool.core.Database.initialize(Database.java:70)
        at mySchool.core.Test.main(Test.java:29)
27.05.2009 16:13:28 mySchool.core.Database initialize
WARNUNG: Initializising Database: error

Wenn der Code nicht ausreicht dann poste ich noch mehr, oder wahrscheinlich geschickter, aber ich weiss nicht wieviel arbeit es dir macht, könntest du ihn komplett auch von meinem svn-repo holen:
myschool - Revision 78: /
 
S

SlaterB

Gast
die Fehlermeldung spricht von Requirement und die Klasse postest du nicht?
ok, offizielle Anforderung: Code reicht nicht aus, bitte poste mehr

ich vermute:
Requirement referenziert andere Objekte, die nicht vorher in der DB gespeichert wurden,
alternativ vielleicht als 'CASCADE INSERT' oder änhlich definieren, so dass automatisch inserted wird,
 

KlinCh

Mitglied
Die Regionen liegen so vor:
(Auszug aus Region.java)
Java:
 public static Region BAWU = new Region(1, "Baden-Württemberg", 1000.0, 1.5,
            new Requirement(Subject.MATH, 5),
            new Requirement(Subject.GERMAN, 3)
           );
...
 public Region(int id, String name, double funds, double secFactor, Requirement... someRequirements){
        allRegions.add(this);
        this.id = id;
        this.funds = funds;
        this.name = name;
        this.securityFactor = secFactor;
        for(Requirement r : someRequirements){
            this.requirements.add(r);
        }        
    }
Dieser Konstruktor added diese zu einer ArrayList, welche dann später in dem static-block der Database.java in die Datenbank abgepeichert wird.(bzw. sollte).

Java:
@Entity
@SequenceGenerator(name="req_id", sequenceName="req_id_seq")
public class Requirement implements Serializable{

    @Id
    @GeneratedValue(generator="req_id", strategy=GenerationType.AUTO)
    int id = -61;     //Das ist nur zum Schauen ob überhaupt IDs generiert werden

    @ManyToOne
    Region region;
    
    @OneToOne
    Subject subject;
    
    @Column(name="clevel")
    int level = 0;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public Subject getSubject() {
        return subject;
    }

    public void setSubject(Subject subject) {
        this.subject = subject;
    }



    public Requirement() {
    }

    public Requirement(Subject anSubject, int level){
        this.subject = anSubject;
        this.level = level;
    }

    @Override
    public String toString() {
           return subject.toString()+" "+level;
    }


}
Java:
@Entity
public class Subject implements Serializable {

    @Transient
    public static ArrayList<Subject> allSubjects = new ArrayList<Subject>();

    @Id
    int id = -64;
    
    private String name;
    "Wirtschaft","Biologie","Erdkunde","Italienisch","Spanisch","Geschichte","Informatik"};

    public static Subject MATH = new Subject(1, "Mathe");
    public static Subject GERMAN = new Subject(2, "Deutsch");
    public static Subject FRENCH = new Subject(3, "Französisch");
    public static Subject ENGLISH = new Subject(4, "Englisch");
    public static Subject SPORT = new Subject(5, "Sport");


   public Subject () {
    }

   public Subject(int id, String name) {
       this.id = id;
        this.name = name;        
        allSubjects.add(this);
    }

Vielleicht ums ein bisschen verständlicher zu machen.
Code:
Player n:1 -> Region 1:n -> Requirement m:1 -> Subject
 
S

SlaterB

Gast
> @OneToOne
> Subject subject;

hast du nicht vielleicht doch mehrere Requirements mit demselben Subject?
bzw. m:1 sagt es ja schon, also ManyToOne,

was genau ist die Integritätsbedingung 'FK7912842313767E40', hast du einen Blick auf die Datenbank und Kenntnis zur Interpretation?
wie wurde die DB angelegt/ gibts ein Skript?
 

KlinCh

Mitglied
> @OneToOne
> Subject subject;

hast du nicht vielleicht doch mehrere Requirements mit demselben Subject?
bzw. m:1 sagt es ja schon, also ManyToOne,
Stimmt, das ist zumindest schonmal ein Fehler, ich habe ihn gefixt, doch das Problem besteht weiterhin.
was genau ist die Integritätsbedingung 'FK7912842313767E40', hast du einen Blick auf die Datenbank und Kenntnis zur Interpretation?
wie wurde die DB angelegt/ gibts ein Skript?

Also ehrlich gesagt ich weiss nicht mal so ganz genau was eine Integritätsbedingung ist, dem Wortlaut nach würde ich Vermuten es ist irgendeine Regel, nach der nur "passende", "sich integrierende" daten eingefügt können.

Wie kann/könnte ich diese Abfragen?
Ich könnte die komplette DB dumpen, hilft dir das?

Also die Datenbank ist eine vanilla javadb, angelegt aus dem kontextmenü von netbeans.
Die ganzen Tabellen werden von Hibernate selbst angelegt:
hibernate.
[XML]<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.DerbyDialect</property>
<property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
<property name="hibernate.connection.url">jdbc:derby://localhost:1527/myschool</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>
...
[/XML]
 
Zuletzt bearbeitet:
S

SlaterB

Gast
naja, da wollen wir mal lieber nicht weiter nachforschen, ManyToOne schon ausprobiert?

als nächstes würde ich dir detaillertes save() vorschlagen, also Arbeit:
speichere zunächst alle Subjekte + commt, klappts oder Exception?
dann alle Regionen, damit dürfte es doch spätestens zu einer Exception beim Commit kommen?
dann nur eine der Regionen, dann 2, dann 3, wann genau ist die minimale Konstellation erreicht?
dann in der letzten Region die enthaltenen Objekte, die Probleme machen könnten, einzeln entfernen bzw. die Objekte in den Objekten usw.
 

KlinCh

Mitglied
Also Abspeichern eines einzelnen Subjects reicht schon für eine Exception.

Code:
SCHWERWIEGEND: Die Anweisung wurde abgebrochen, weil sie in einer für 'SUBJECT' definierten Vorgabe für einen eindeutigen oder Primärschlüssel bzw. für einen von 'SQL090527223012440' bezeichneten eindeutigen Index zu einem duplizierten Schlüsselwert geführt hätte.
...

eigentlich klarer Fall, aber ich hatte die Datenbank vorher extra gelöscht und neu angelegt um eben dies auszuschließen; dann aber ist mir aufgefallen ,dass das initialize() zweimal aufgerufen wird.(für mich ein Mysterium) und hab das .save zu .saveOrUpdate geändert. und es funktionierte.

-> Danach(also eigentlich schon kurz bevor) fiel mir auf, dass ich beim ursprünglichen Code nur ein .update(s) stehen hatte und das im Zusammenhang mit dem zweimaligen Aufrufen von initialize() war wohl der Fehler.

Jetzt frag ich mich aber noch wieso initialize() zweimal aufgerufen wird.
Testanordnung:
eine Datei Test.java: die ich immer starte zum Testen
Java:
public class Test {
    public static void main(String[] args){
        Database.initialize();     
    }
}
+nochmal die Database.java:
Java:
public class Database {

    static boolean isInitializised = false;
    
    static {
        if(isInitializised == false){
            initialize();
        }
    }
    public static void initialize(){
        Logger logger = Logger.getLogger(Database.class.getName());
        logger.log(Level.INFO, "Initializising Database");
        isInitializised = true;
        Session session = InitHibernate.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        try{
            /* Läd alle Fächer in die Datenbank */
            logger.log(Level.INFO, "Loading all Subjects into DB");
            for(Subject s : Subject.allSubjects){
                logger.log(Level.INFO, "saveOrUpdate Subject :"+s.toString()+", ID: "+s.getId());
               session.saveOrUpdate(s);

           }

            /* Läd alle Regionen in die Datenbank */
            logger.log(Level.INFO, "Loading all Regions into DB");
            for(Region r : Region.allRegions){
                session.saveOrUpdate(r);
                logger.log(Level.INFO, "saveOrUpdate Region :"+r.toString()+", ID: "+r.getId());
            }
            /* Läd alle ChaosEvents in die Datenbank */
            logger.log(Level.INFO, "Loading all ChaosEvetns into DB");
            for(ChaosEvent ce : ChaosEvent.allChaosEvents){
                session.saveOrUpdate(ce);
                logger.log(Level.INFO, "saveOrUpdate ChaosEvent :"+ce.toString()+", ID: "+ce.getId());
            }

//            session.saveOrUpdate(Subject.ENGLISH);
            

            session.getTransaction().commit();
            logger.log(Level.INFO, "Initializising Database: successfull");

        } catch(HibernateException ex){
            session.getTransaction().rollback();
            ex.printStackTrace();
            logger.log(Level.WARNING, "Initializising Database: error");
        }
    }
 

ck2003

Mitglied
...
eigentlich klarer Fall, aber ich hatte die Datenbank vorher extra gelöscht und neu angelegt um eben dies auszuschließen; dann aber ist mir aufgefallen ,dass das initialize() zweimal aufgerufen wird.(für mich ein Mysterium) und hab das .save zu .saveOrUpdate geändert. und es funktionierte.

-> Danach(also eigentlich schon kurz bevor) fiel mir auf, dass ich beim ursprünglichen Code nur ein .update(s) stehen hatte und das im Zusammenhang mit dem zweimaligen Aufrufen von initialize() war wohl der Fehler.

Jetzt frag ich mich aber noch wieso initialize() zweimal aufgerufen wird
....

Kurz und knapp: weil du es zweimal aufrufst. Zuerst im statischen Block in Database und dann in deiner Test-Klasse.
 

KlinCh

Mitglied
Stimmt, das mit dem isInitialied ist so wie es war, natürlich schwachsinn; kann spät abends schonmal passieren ;-)

Momentan scheint alles zu funktionieren.
Vielen Dank dir und SlaterB
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Hibernate/Spring JPA: eigene ID generieren Data Tier 5
Avalon @ManyToOne Hibernate oder JPA? Data Tier 5
D Hibernate Hibernate mit MariaDB Data Tier 1
ToBJo Hibernate Glassfish deploy mit Hibernate schlägt fehl Data Tier 1
C JPA Hibernate Map<String,String> richtig mappen Data Tier 2
S JPA Hibernate Search & EclipseLink (oder OpenJPA) Data Tier 0
R JPA Probleme mit Wechsel von EclipseLink auf Hibernate Data Tier 4
ARadauer Hibernate Entität readonly laden... Data Tier 1
G Hibernate SQL in Hibernate: Keine Parameter mit Index? Data Tier 2
P Wildfly + Hibernate + SQL Server Data Tier 0
E JPA Hibernate Query mit Timestamp hat seltsames Verhalten Data Tier 1
M Eclipse 4 RCP Hibernate Problem Data Tier 3
C Hibernate ProgressBar updaten mit Daten aus Hibernate Data Tier 4
B Hibernate und MySQL testen Data Tier 8
I Hibernate HQL: generiertes SQL ausgeben Data Tier 1
R mapping-file für hibernate zum Überschreiben der Annotationen Data Tier 7
R Hibernate Hibernate und Logback Data Tier 2
R Hibernate möchte Schema zwei mal undeployen Data Tier 2
F Hibernate Hibernate / JPA Data Tier 4
E Hibernate: Session vs EntityManager Data Tier 3
C Hibernate Hibernate Code Generation Data Tier 3
S Hibernate Mehrfachverbindung mit Hibernate Data Tier 3
M Hibernate Einstiegsfrage Data Tier 5
M Exception in thread "main" org.hibernate.MappingException: java.lang.ClassNotFoundException: Message Data Tier 4
S Hibernate Einstieg in Hibernate 3.2 sinnvoll? Data Tier 8
P JPA Eigene Vererbungsstrategie mit JPA / Hibernate Data Tier 2
J Hibernate Problem bei Master-Detail-Tabellen Data Tier 5
Y Jboss seam-hibernate-jpa Data Tier 5
RaoulDuke Hibernate Map<String,String> mit Annotations mappen Data Tier 2
M Hibernate Hibernate with GWT Data Tier 4
C Hibernate JPA mysql db erstellen Data Tier 4
M Hibernate Hibernate liest Daten zu oft aus! Data Tier 16
pg1337 Hibernate Fragen Data Tier 11
D Probleme bei Left Joins mit Hibernate createCriterias() Data Tier 2
D Hibernate probleme mit Verlinkungstabelle Data Tier 4
2 Hibernate Annotations Data Tier 7
G Hibernate select update no wait Data Tier 8
Z Hibernate: Many-To-Many nur eine bestimmte Spalte Data Tier 3
K Hibernate - Envers - Erzeugung der SQL Skripte Data Tier 4
G Hibernate 1:n Beziehung mit Vererbung Data Tier 5
D Hibernate-Criteria-API (Projections und MAX-Funktion) Data Tier 6
L Hibernate: failed to lazily initialize a collection of role Data Tier 3
S Hibernate hibernate.cfg.xml Data Tier 14
D JPA vs Hibernate.cfg und Entitymanager Data Tier 6
H Hibernate - Mapping für Enumeration Data Tier 1
R Hibernate Criteria Abfrageproblem Data Tier 2
A Hibernate und jdbc zusammen Data Tier 4
D Mit Hibernate aus JUnit ein DB-Schema erzeugen Data Tier 6
S [Hibernate] No Persistence provider for EntityManager Data Tier 5
B Problem mit org.hibernate.LazyInitializationException Data Tier 11
G Hibernate HQL und Interface Data Tier 4
G JSF Hibernate no session or session was closed Data Tier 12
T JPA2/Hibernate: Many-to-Many-Relation wird u.a. beim löschen nicht aktualisiert Data Tier 14
S (Hibernate) Mapping einer Datenbanktabelle mit mehreren Fremdschlüssel Data Tier 7
X [Hibernate] Zusammengesetzte Entities möglich? Data Tier 7
N Hibernate Fake? Data Tier 2
S Problem beim Insert mit Hibernate Data Tier 9
V Hibernate Projection Data Tier 2
T org.hibernate.impl.SessionFactoryImpl Memory Leak Data Tier 10
G Hibernate Composite key Data Tier 11
X [Hibernate] Connection Pool - MinSize ? Data Tier 2
R Hibernate Criteria OR Data Tier 2
T hibernate/jpa abgefragte Listen immer mit Null-Werten gefüllt Data Tier 8
X [Hibernate] Anderen Connection Pool - Vorschläge? Data Tier 3
ARadauer Hibernate DDL Loggen Data Tier 6
G Hibernate abfrage Collection Data Tier 3
X [Hibernate] ReverseEngineering - Eigene Strategy verwenden? Data Tier 3
R Hibernate Criteria .group größer als Data Tier 5
R Hibernate daten laden Data Tier 7
H [Hibernate]1:1 Beziehung Data Tier 8
H [Hibernate]No CurrentSessionContext configured! Data Tier 6
X [Hibernate] Lässt sich die Dauer eines SELECTs loggen? Data Tier 4
R Hibernate n:n Relationtabelle mit Date Data Tier 3
H [Hibernate] Unknown Entity Data Tier 3
H [Hibernate] Configuration Data Tier 3
C [Hibernate] Generierung von hbm.xml to Java Data Tier 4
lumo Eclipse & JPA & Hibernate & Derby Data Tier 5
J Zufallsauswahl aus ResultList bei JPA(Hibernate) / Performance Data Tier 3
M Hibernate: Datum 0001-01-01 erzeugt null-Datum Data Tier 4
G Datenbankzugriff mit Hibernate Data Tier 7
Y Hibernate - Angabe des Schemas Data Tier 6
LadyMilka (Hibernate) in Criteria implizierter Join durch Subquery's Data Tier 8
M Hibernate Mehr als 1 Object speichern? Data Tier 18
M Unerklärliche Hibernate Exception Data Tier 20
LadyMilka (Hibernate) subquery in FROM-Clause Data Tier 9
haemi Viele DTOs in hibernate IdentityMap Data Tier 3
LadyMilka (hibernate) UNION dem Dialekt hinzufügen Data Tier 3
M Hibernate + Oracle 10g XE Data Tier 3
lumo Hibernate - entity class not found Data Tier 5
P SQL PRoblem Hibernate? Data Tier 8
J Vererbung mit JPA / Hibernate - pro/contra Data Tier 3
T JBoss/Hibernate: Abfrage dauert lang + hohe CPU? Data Tier 19
7 Hibernate-Abfrage (SubSelect im FROM) Data Tier 2
G Hibernate: many-to-one - Verwaiste Datensätze löschen Data Tier 2
G Layer für Datenbankzugriff Hibernate Data Tier 5
G Hibernate Zwischentabelle Data Tier 2
Java.getSkill() Hibernate und Spalte vom Typ xml Data Tier 6
G Hibernate 0...1 : 1 Beziehung Data Tier 6
G Hibernate mehrere @oneToone Data Tier 2
G Hibernate 1:n, 1:1 Data Tier 26

Ähnliche Java Themen

Neue Themen


Oben