# BatchUpdateException beim schreiben in DB



## k4lle (4. Okt 2007)

Ich weiß einfach nicht genau woran es liegt. Bekomme immer folgende Exception:


```
exception 

javax.servlet.ServletException: could not insert: [beans.User]
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:154)


root cause 

org.hibernate.exception.SQLGrammarException: could not insert: [beans.User]
	org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
	org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
	org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2267)
	org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
	org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
	org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
	org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
	org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
	org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
	org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
	org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
	beans.UserHandler.processAction(UserHandler.java:45)
	javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
	javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:487)
	javax.faces.component.UICommand.broadcast(UICommand.java:78)
	javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
	javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
	org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
	org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
	org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)


root cause 

java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALTER, USER_ID) values ('tim', 0, 0)' at line 1
	com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1257)
	com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:943)
	org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
	org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:34)
	org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2247)
	org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2660)
	org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:56)
	org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
	org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
	org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
	org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
	org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
	org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
	beans.UserHandler.processAction(UserHandler.java:45)
	javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
	javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:487)
	javax.faces.component.UICommand.broadcast(UICommand.java:78)
	javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
	javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
	org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
	org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
	org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
```

Es muss damit zu tun haben, wie der name der exception schon sagt "You have an error in your SQL syntax". aber warum? ich zeige mal die hibernate-cfg.xml und mapping-datei.

hibernate-cfg.xml

```
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
      <session-factory>    
     
	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
	<property name="connection.url">jdbc:mysql://localhost:3306/USERTEST</property>
	<property name="connection.username">*****</property>
	<property name="connection.password">*****</property>
        
        <property name="connection.autocommit">true</property>       
      
      <property name="hibernate.hbm2ddl.auto">update</property>      
      <property name="hibernate.show.sql">true</property>         
      <property name="hibernate.jdbc.batch_versioned_data">true</property>
      <property name="hibernate.jdbc.batch_size">1</property>        
        
        
        <property name="dialect">
         org.hibernate.dialect.MySQLDialect
        </property>
        
        <mapping resource="beans/User.hbm.xml" />
      </session-factory>
    </hibernate-configuration>
```

User.hbm.xml

```
<?xml version="1.0"?>
  <!DOCTYPE hibernate-mapping PUBLIC
  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > 
  <hibernate-mapping> 
      <class name="beans.User" table="USER" >
          <id name="userId" type="java.lang.Integer" column="USER_ID" >
                <generator class="assigned" />
          </id>
          <property name="name" type="java.lang.String" column="NAME"/>          
          <property name="alter" type="java.lang.Integer" column="ALTER"/>          
      </class> 
  </hibernate-mapping>
```

In der MySQL DB habe ich eine Tabelle mit 3 Spalten USER_ID, NAME und ALTER angelegt. 
Wenn ich in Zeile 15 der hibernate-cfg.xml den Wert auf create ändere, dann wird zumindest schonmal die Tabelle user gelöscht. Also klappt der DB-Zugriff schonmal. 
Ich will ein Objekt speichern, aber anscheinend wird die falsche MySQL-Syntax benutzt. Verstehe aber nicht warum, da ich ja die Attribute des Objektes durch die mapping-datei den Spalten zuordne und da mache ich ja ansonsten nichts.
Wenn ich Zeile 17 und 18 der hibernat-cfg.xml weglasse, dann steht in zeile 9 der exception:

```
org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
```

ich weiß nicht woran es liegt und bin bisher auch im inet nicht besonder weiter gekommen. deswegen hoffe ich jemand kann mir helfen.[/code]


----------



## RoNa (4. Okt 2007)

Kann es vielleicht damit zusammenhängen, dass das eingesetzte Datebanksystem Batch nicht unterstützt, und die Befehle
http://www.dpunkt.de/java/Referenz/Das_Paket_java.sql/15.html#addBatch()
http://www.dpunkt.de/java/Referenz/Das_Paket_java.sql/26.html#executeBatch()

nicht ausgeführt werden können? Gibt es vielleicht in Deiner Konfiguration Batch an- und auszuschalten? Versuch's mal ohne batch.

Viel Erfolg,

Robert


----------



## k4lle (4. Okt 2007)

Ich muss ganz ehrlich sagen, mit Batch habe ich mich bisher noch gar nicht so befasst. Habe da irgendwo was zu gelesen und das einfach mal mit reingepackt. Aber nicht desto trotz, wenn ich das wieder herausnehme, dann bekomme ich immer noch die gleiche Exception.


```
org.hibernate.exception.SQLGrammarException: could not insert: [beans.User]
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALTER) values ('tim', 0)' at line 1
```

vielleicht hat es ja damit zu tun, dass ich 2 Eingabefelder habe wo der name und das alter eingegeben werden muss. 
in der tabelle habe ich dann 3 spalten.
name und alter sollen in der db gespeichert werden.
die user_id ist primärschlüssel und soll von hibernate erzeugt werden.

wenn ich die exception lese, dann hört es sich ja so an,
dass beim insert-befehl die falsche syntax benutzt wird. aber das soll ja alles durch hibernate regeln.

hat noch jemand ne ahnung?
[/quote]


----------



## ms (4. Okt 2007)

'ALTER' ist ein reserviertes Wort. Probier mal zum Testen ALTER1 oder AGE oder ....

ms


----------



## k4lle (4. Okt 2007)

ich esel....
du hattest natürlich recht. das schlimme ist, dass ich vorhin noch gelesen habe, dass man keine SQL-Schlüsselwörter als Spaltennamen nehmen darf wie z.B. DATE. Ich habe die ganze Zeit an alter table.... gedacht, aber da wäre ich so schnell nicht drauf gekommen. 

vielen dank.... traurig, sitze schon den ganten tag daran ;-)


----------



## k4lle (4. Okt 2007)

jetzt habe ich nur noch ein problem. 
Wenn ich meine Anwendung starte, dann wird sofort von der index.jsp zur formular.jsp weitergeleitet. Also wird der JSF-Lebenszyklus durchlaufen. Der besteht ja aus 6 Phasen. Ich glaube in der 4 werden die eingegeben Wert den Beans übergeben und in der 5 werden die Aktion-Methode aufgerufen.

Jetzt ist das aber so, dass meine Propertys die gespeichert werden sollen, int name und string age default-mäßig mit 0 und "" initialisiert werden.
Wenn also jetzt der Lebenszyklus durchlaufen wird, dann werden also beim Betätigen des Buttons die default-Werte gespeichert.

Habe das mal getestet, indem ich name und age Werte zuweise.

So ist das natürlich nicht gewollt. Es sollen natürlich nur die eingegeben Werte gespeichert werden.

Sehe ich das richtig und kann mir da jemand was zu sagen?


----------



## k4lle (5. Okt 2007)

hab schon wieder ein neues problem. wenn jemand was dazu sagen kann, wäre das sehr schön. sonst muss ich wieder so lange rumsuchen ....


```
exception

javax.servlet.ServletException: could not insert: [beans.Maschinendaten]
   javax.faces.webapp.FacesServlet.service(FacesServlet.java:154)


root cause

org.hibernate.exception.ConstraintViolationException: could not insert: [beans.Maschinendaten]
   org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
   org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:40)
   org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2158)
   org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2638)
   org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:48)
   org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
   org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
   org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
   org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
   org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
   org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
   beans.MaschinendatenHandler.processAction(MaschinendatenHandler.java:34)
   javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
   javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:487)
   javax.faces.component.UICommand.broadcast(UICommand.java:78)
   javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
   javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
   org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
   org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
   org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
   javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)


root cause

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'betriebsmittel' cannot be null
   com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
   com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
   com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
   com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
   com.mysql.jdbc.Connection.execSQL(Connection.java:3256)
   com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1313)
   com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1585)
   com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1500)
   com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1485)
   org.hibernate.id.insert.AbstractSelectingDelegate.performInsert(AbstractSelectingDelegate.java:33)
   org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2158)
   org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2638)
   org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:48)
   org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
   org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
   org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
   org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
   org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
   org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
   org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
   org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
   beans.MaschinendatenHandler.processAction(MaschinendatenHandler.java:34)
   javax.faces.event.ActionEvent.processListener(ActionEvent.java:51)
   javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:487)
   javax.faces.component.UICommand.broadcast(UICommand.java:78)
   javax.faces.component.UIViewRoot._broadcastForPhase(UIViewRoot.java:97)
   javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:171)
   org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:32)
   org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
   org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
   javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
```

Ich habe eine SQL-DB angelegt. Die Spalten der Tabelle sind so abgelegt, das sie nicht null sein können. Wenn ich not null rausnehme, dann wird in alle Spalten der Tabelle der wert null eingetragen (das gleiche passiert, wenn ich <property name="hbm2ddl.auto"></property> auf create setze)

beim mappen dürfte eigentlich kein fehler aufgetereten sein. constraint hat ja eigentlich was mit wertebeschränkung zu tun. Da steht ja column betriebsmittel cannot be null. soll sie ja auch nicht...

kann da jemand was zu sagen?


----------



## RoNa (5. Okt 2007)

Guten Abend,

ist der Fehler nicht, das die Spalte 'betriebsmittel' nicht null sein darf ? So steht es jedenfalls im Stack Trace.

Robert


----------



## k4lle (6. Okt 2007)

genau das ist der fehler. er sagt das bei allen String-attributen die in varchar{45}-columns gemappt werden. ich gebe werte in mein formular ab und drücke auf speichern. das passiert aber leider nicht. 

also könnte es ja wirklich damit zu tun haben, dass die eingegeben werte nicht gespeichert werden und deswegen sagt er 
spalte blabla darf nicht null sein.  obwohl ich mir die bean propertys mit system.out.println ausgeben lasse und ich bekomme meinen eingegeben werte angezeigt. 

also wenn der fehler kommt, müßte es ja so sein, dass er die werte nicht richtig speichert, da ja im formular definitiv werte eingetragen wurden und deswegen kommt der fehler spalte blablabla darf nicht null sein. 

oder?


----------



## k4lle (6. Okt 2007)

Jetzt weiß ich woran es liegt. Also ich weiß nicht wie ich es löse, aber ich weiß was da schief geht....

Ich habe mal zum Test den Bean-Properties age und name beim deklarieren Wert zugewiesen:
private String name="Tim", private int age="23";
Wenn ich jetzt die Anwendung starte, dann stehen diese beiden Werte in den Eingabefeldern und wenn ich auf speichern drücke werden sie gespeichert. Da sehe ich wenigstens, dass das Speichern schonmal klappt, aber aber so will ich das natürlich nicht.

Bei mir sollen die Eingabefelder natürlich leer sein und es sollen Werte eingegeben werden können und gespeichert werden können. Ich zeige euch mal meinen Code. Es kann ja eigentlcih nur daran liegen, dass die Bean-Properties nicht mit den eingegeben Werten aktualisiert werden. 

Klasse User

```
package beans;

public class User {
	private int userId;
	private String name;
	private int age;
	
	public void setUserId(int userId){
		this.userId = userId;
		//System.out.println("setUserId" + userId);
	}
	public int getUserId(){
		//System.out.println("getUserId" + userId);
		return userId;
	}
	public void setName(String name){
		this.name = name;
		//System.out.println("getName" + name);
	}
	public String getName(){
		//System.out.println("getName" + name);
		return name;
	}
	public void setAge(int age){
		this.age = age;
		//System.out.println("getAge" + age);
	}
	public int getAge(){
		//System.out.println("getAge" + age);
		return age;
	}
}
```

Klasse UserHandler

```
package beans;


import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import Util.HibernateUtil;

public class UserHandler implements ActionListener{
	
	public User user;
	
	public UserHandler(){
		this.user = new User();
	}	
	
	public User getUser(){
		return user;
	}
	public void setUser(User user){
		this.user = user;
	}

	public void processAction(ActionEvent ae) throws AbortProcessingException {	
		
			Session session = HibernateUtil.getSessionFactory().openSession();
			session.beginTransaction();
			session.saveOrUpdate(user);
			session.getTransaction().commit();
			session.close();
	}
}
```

Mein Formular sieht so aus:

```
<h:panelGrid columns="2">
		<h:outputLabel id="name" value="Name"></h:outputLabel>
		<h:inputText id="name_eingabe" size="14" required="true" 
		value="#{UserHandler.user.name}"></h:inputText>
		<h:outputLabel id="alter" value="Alter"></h:outputLabel>
		<h:inputText id="alter_eingabe" size="14"  required="true"
		value="#{UserHandler.user.age}"></h:inputText>
		<h:commandButton id="button" value="speichern">
		<f:actionListener type="beans.UserHandler"/>
		</h:commandButton>
		<h:outputLabel id="leer"></h:outputLabel>
	</h:panelGrid>
```

Egal ob der Code an der einen oder anderen Stelle nicht so gut aussieht, aber ich will einfach nur wissen wieso die Bean-Properties nicht mit dein eingegeben Werten aktualisiert werden, obwohl sie ja an die Komponente inputText gebunen sind...

Wer kann mir dazu was sagen?


----------



## k4lle (7. Okt 2007)

ich hoffe irgendein jsf-crack kann noch was dazu sagen ? 
ich komme einfach nicht darauf woran es liegt.... ;-(


----------



## Guest (8. Okt 2007)

hi,

ok bin kein jsf profi aber zwei tipps kann ich dir trotzdem geben:
1. wieso beim actionlistener beans.Userhandler und beim inputfield nur Userhandler? was hast du da in der faces-config.xml konfiguriert?
2. nächstes mal faces-config.xml posten
3. hier hats ein super tutorial mit beispielen: http://www.coreservlets.com/JSF-Tutorial/

greetz


----------



## k4lle (8. Okt 2007)

es lag in der tat daran, dass ich ein action-event aufgerufen habe. dabei ist genau das von mir gedachte problem aufgetreten. die eingegebenen werte wurden nicht in der phase "update model values" aktualisiert, da beim action-event phasen übersprungen werden. 
jetzt habe ich einfach mit dem attribut "action" meine action methode aufgerufen und siehe da, es klappt so wie es soll. wenn mittels action eine action-methode aufgerufen wird, dann wird der lebenszyklus neu durchlaufen. genau wie von mir gewollt, werden die eingegebenen werte in den bean-propertys gespeichet. 

so jetzt kann ich endlich weiter machen und habe wieder was dazu gelernt...


----------

