-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: Inserting to SQL Server 2005 consistently crashes
PostPosted: Mon Sep 08, 2008 8:20 am 
Newbie

Joined: Mon Sep 08, 2008 7:51 am
Posts: 7
I have a working JTDS connection to SQL Server 2005, from which I can read and update, however when trying to insert new records, I get this stack trace:

Message: java.sql.SQLException: Parameter #2 has not been set.
net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareSQL(ConnectionJDBC2.java:613)
net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:504)
org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:73)
org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.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.ejb.event.EJB3MergeEventListener.saveWithGeneratedId(EJB3MergeEventListener.java:43)
org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:186)
org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:228)

After doing some googling it appears that its because the id column which is the primary key in the table is not being set as it will automatically be assigned by SQL Server (presumably?).

Any advice or help on this would be great

Thanks

Tim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 8:40 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
What does the generated sql look like? Is hibernate definitely trying to set the ID column? It would be helpful to see your mapping file/annotations for the class in question.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 8:47 am 
Newbie

Joined: Mon Sep 08, 2008 7:51 am
Posts: 7
thatmikewilliams wrote:
What does the generated sql look like? Is hibernate definitely trying to set the ID column? It would be helpful to see your mapping file/annotations for the class in question.


Here is the full debugging output generated before the error:

DEBUG - opened session at timestamp: 12208764619
DEBUG - begin
DEBUG - opening JDBC connection
DEBUG - total checked-out connections: 0
DEBUG - using pooled JDBC connection, pool size: 0
DEBUG - current autocommit status: true
DEBUG - disabling autocommit
DEBUG - after transaction begin
DEBUG - id unsaved-value: 0
DEBUG - transient instance of: com.foo.jpaweb.model.Author
DEBUG - merging transient instance
DEBUG - saving [com.foo.jpaweb.model.Author#<null>]
DEBUG - executing insertions
DEBUG - Wrapped collection in role: com.foo.jpaweb.model.Author.books
DEBUG - executing identity-insert immediately
DEBUG - Inserting entity: com.foo.jpaweb.model.Author (native id)
DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG - insert into dbo.authors (name, id) values (?, ?)
Hibernate: insert into dbo.authors (name, id) values (?, ?)
DEBUG - preparing statement
DEBUG - Dehydrating entity: [com.foo.jpaweb.model.Author#<null>]
DEBUG - binding 'sdfsd' to parameter: 1
DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - closing statement
DEBUG - could not insert: [com.foo.jpaweb.model.Author] [insert into dbo.authors (name, id) values (?, ?)]
java.sql.SQLException: Parameter #2 has not been set.
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareSQL(ConnectionJDBC2.java:613)

So it looks like the SQL is:

insert into dbo.authors (name, id) values (?, ?)

My persistence.xml file is:

<persistence>
<persistence-unit name="jpaweb" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.connection.driver_class" value="net.sourceforge.jtds.jdbc.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value="mypassword"/>
<property name="hibernate.connection.url" value="jdbc:jtds:sqlserver://localhost:1433/demo;instance=sqlserver"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.connection.release_mode" value="auto" />
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.DriverManagerConnectionProvider" />
</properties>
</persistence-unit>
</persistence>

And my entity file is actually written in scala, but should still make sense for non-scala guys:

@Entity
@Table(){val name="authors", val schema="dbo"}
class Author {
// the _ is just a scala convention for saying "Any", or in this case, any Long.
@Id
@GeneratedValue(){val strategy = GenerationType.IDENTITY}
var id : Long = _

var name : String = ""

@OneToMany(){val mappedBy = "author", val targetEntity = classOf[Book]}
var books : java.util.Set[Book] = new java.util.HashSet[Book]()
}


As you can see, its very simple. Im just trying to get a tester working, so im not sure why such a simple example is going wrong.

Does that illuminate the problem at all?

Cheers

Tim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 10:15 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Does the java code generated by scala look good? What version of hibernate are you using? I did a quick test on 3.2.6 (without scala) and seems fine to me. My debug statements look almost identical and the generated SQL is correct.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 10:22 am 
Newbie

Joined: Mon Sep 08, 2008 7:51 am
Posts: 7
The bytecode looks good yes - is there a way of stopping hibernate trying to insert a value for the ID column?

Some annotation im missing to stop it inserting a value?

cheers

Tim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 10:43 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Marking the ID column as IDENTITY should prevent it being included in the insert - this works for me. What version of hibernate and annotations are you using?

Code:
@Entity
@Table(name="mike_test", schema="asd")
public class Author {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   Long id;

   String name;
}


Code:
DEBUG: (AbstractSaveEventListener) saving [model.Author#<null>]
DEBUG: (AbstractSaveEventListener) executing insertions
DEBUG: (AbstractSaveEventListener) executing identity-insert immediately
DEBUG: (AbstractEntityPersister) Inserting entity: model.Author (native id)
DEBUG: (AbstractBatcher) about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG: (SQL) insert into asd.mike_test (name) values (?)
Hibernate: insert into asd.mike_test (name) values (?)
DEBUG: (AbstractBatcher) preparing statement
DEBUG: (AbstractEntityPersister) Dehydrating entity: [model.Author#<null>]
DEBUG: (StringType) binding null to parameter: 1
DEBUG: (AbstractBatcher) about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG: (AbstractBatcher) closing statement


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 11:03 am 
Newbie

Joined: Mon Sep 08, 2008 7:51 am
Posts: 7
Hmmmmm, how strange. When it loads I see:

DEBUG - Insert 0: insert into dbo.authors (name, id) values (?, ?)

But it shouldn't be using the id col for inserting right? I've even tried explicitly declaring it as not insertable and that doesn't work either:

@Id
@GeneratedValue(){val strategy = GenerationType.IDENTITY}
@Column(){val insertable = false}
var id : Long = _

The byte code looks like this:

import java.rmi.RemoteException;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import scala.ScalaObject;
import scala.ScalaObject.class;

@Entity
@Table(name="authors", schema="dbo")
public class Author
implements ScalaObject
{

@OneToMany(mappedBy="author", targetEntity=Book.class)
private Set books;
private String name;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(insertable=false)
private long id;

public Author()
{
this.books = new HashSet(); }
@OneToMany(mappedBy="author", targetEntity=Book.class)
public void books_$eq(Set<Book> x$1) { this.books = x$1; }
@OneToMany(mappedBy="author", targetEntity=Book.class)
public Set<Book> books() { return this.books;
}

public void name_$eq(String x$1)
{
this.name = x$1; }
public String name() { return this.name;
}

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(insertable=false)
public void id_$eq(long x$1)
{
this.id = x$1; }
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(insertable=false)
public long id() { return this.id;
}

public int $tag()
throws RemoteException
{
return ScalaObject.class.$tag(this);
}
}


If all else fails I might have to swap the persistance part of my project back to Java :-(

That code looks right tho yeah? Im using JPA 3.0 I do belive

Cheers

Tim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 12:35 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Generated java looks weird because there are identical annotations in multiple locations. However, it doesn't seem to be causing your problem. You should check this with a clean java implementation (no scala and multiple annotations). Otherwise, upgrade to the latest version of your entity manager or try alternatives.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 7:18 pm 
Newbie

Joined: Mon Sep 08, 2008 7:51 am
Posts: 7
Ok, this just got very strange.

I've redone things in pure java, and I see see the same issue!!!

Im using Hibernate 3.3.2.GA and my java entity looks like this:


Code:

@Entity
@Table(name="authors", schema="dbo")
public class Author {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String name;

  @OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
  private Set<Book> books = new HashSet<Book>();

  public Long getId() {
    return id;
  }

  public String getName() {
    return name;
  }

  public Set<Book> getBooks() {
     return books;
  }

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

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

  public void setBooks(Set<Book> books) {
    this.books = books;
  }
}



Am I just being plain dumb here? It really feels like it!! If its not working with a java version, then what on earth could be wrong?

Im calling em.persist in my application code

Cheers

Tim


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 08, 2008 7:39 pm 
Newbie

Joined: Mon Sep 08, 2008 7:51 am
Posts: 7
Ah I managed to fix it...

It appears that if the id field has no initial value, for whatever reason it bombs out. By just setting a default in the class it fixes it. A total nightmare....

For completness sake and anyone who also has these troubles, here is my final scala class:


Code:

@Entity
@Table(){val name="authors", val schema="dbo"}
class Author {
  @Id
  @GeneratedValue(){val strategy = GenerationType.IDENTITY}
  @Column(){val insertable = false, val unique = true}
  var id : Long = 100

  var name : String = ""

  @OneToMany(){val mappedBy = "author", val targetEntity = classOf[Book]}
  var books : java.util.Set[Book] = new java.util.HashSet[Book]()
}



Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.