This test case produces the following exception. Is it safe to say that transient instances must be passed to merge, while only detached instances (and persistent of course) are safe to pass to update() ? using rc2
Code:
package net.dbyrne.hibernate;
import java.util.Date;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.auction.AuctionItem;
import org.hibernate.auction.Bid;
import org.hibernate.auction.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hsqldb.Server;
public class HibernateTestCase extends TestCase {
private static Log log = LogFactory.getLog(HibernateTestCase.class);
protected Configuration conf;
protected SessionFactory sessionFactory;
private static Server server;
private static String SERVER_PROPS = "database.0=mem:test";
private Long auctionItemId ;
private Integer userId = new Integer(99);
private String bidId = "someId";
int bidAmount = 88;
private Date bidDate = new Date();
protected void setUp() {
server = new Server();
server.putPropertiesFromString(SERVER_PROPS);
server.start();
conf = new Configuration().configure();
sessionFactory = conf.buildSessionFactory();
SchemaExport schemaExport = new SchemaExport(conf);
schemaExport.create(true, true);
Session session = sessionFactory.openSession();
Transaction trans = session.beginTransaction();
User user = new User();
user.setMyUserId(userId);
user.setEmail("dennis@dbyrne.net");
user.setFirstName("dennis");
user.setInitial('C');
user.setLastName("byrne");
user.setPassword("scooter");
user.setUserName("CIA-leak");
session.save(user);
trans.commit();
Transaction trans2 = session.beginTransaction();
AuctionItem ai = new AuctionItem();
ai.setCondition(4);
ai.setDescription("desc.");
ai.setEnds(new Date());
session.save(ai);
trans2.commit();
Transaction trans3 = session.beginTransaction();
Bid bid = new Bid();
bid.setMyBidId(bidId);
bid.setItem(ai);
bid.setBidder(user);
bid.setDatetime(bidDate);
bid.setAmount(bidAmount);
ai.setSeller(user);
ai.setSuccessfulBid(bid);
session.save(bid);
trans3.commit();
auctionItemId = ai.getId();
session.close();
log.info("finished creating test data");
}
protected void tearDown() throws Exception {
sessionFactory.close();
sessionFactory = null;
server.stop();
server = null;
super.tearDown();
}
public void testUpdate(){
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hql = "FROM User WHERE id = " + userId.toString();
User user = (User) session.createQuery(hql).uniqueResult();
hql = "FROM AuctionItem where id = " + auctionItemId.toString();
AuctionItem ai = (AuctionItem) session.createQuery(hql).uniqueResult();
Bid bid = new Bid();
bid.setMyBidId(bidId); // same id
bid.setBidder(user); // same user
bid.setItem(ai); // same item
bid.setDatetime(new Date()); // diff date
bid.setAmount(bidAmount); // same amount
// session.merge(bid); // no exception
session.update(bid); // cause java.lang.NullPointerException
tx.commit();
session.close();
}
}
Code:
<?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 package="org.hibernate.auction">
<class name="Bid">
<comment>A bid or "buy now" for an item.</comment>
<id name="myBidId" type="string">
<generator class="assigned" />
</id>
<!-- <discriminator type="char">
<column name="isBuyNow">
<comment>Y if a "buy now", N if a regular bid.</comment>
</column>
</discriminator> -->
<natural-id>
<many-to-one name="item" />
<property name="amount" />
</natural-id>
<property name="datetime" not-null="true" column="`datetime`" />
<many-to-one name="bidder" not-null="true" />
<!--
<subclass name="BuyNow"
discriminator-value="Y"/> -->
</class>
</hibernate-mapping>
Code:
java.lang.NullPointerException
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkNaturalId(DefaultFlushEntityEventListener.java:70)
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:145)
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:97)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:195)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:345)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at net.dbyrne.hibernate.HibernateTestCase.testUpdate(Unknown Source)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:416)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:138)