Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#1828 closed defect (fixed)

Calling Directory.getNew() multiple times with overlapping non-existing paths

Reported by: Nicklas Nordborg Owned by: everyone
Priority: major Milestone: BASE 3.3
Component: core Version:
Keywords: Cc:

Description

Calling Directory.getNew() multiple times with overlapping non-existing paths causes a database exception since the BASE core try to create the non-existing directories each time the Directory.getNew() method is called.

Change History (3)

comment:1 Changed 8 years ago by Nicklas Nordborg

(In [6508]) References #1828: Calling Directory.getNew() multiple times with overlapping non-existing paths

Added a test case. Here is the current stack trace:

net.sf.basedb.core.DatabaseException: ERROR: duplicate key value violates unique constraint "Directories_name_parent_id_key"
  Detail: Key (name, parent_id)=(foo, 536) already exists.
	at net.sf.basedb.core.HibernateUtil.commit(HibernateUtil.java:1173)
	at net.sf.basedb.core.DbControl.commit(DbControl.java:505)
	at TestDirectory.test_create_multiple(TestDirectory.java:167)
	at TestDirectory.test_all(TestDirectory.java:67)
	at TestDirectory.main(TestDirectory.java:47)
Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "Directories_name_parent_id_key"
  Detail: Key (name, parent_id)=(foo, 536) already exists.
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:363)
	at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:105)
	at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2435)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2875)
	at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
	at net.sf.basedb.core.HibernateUtil.commit(HibernateUtil.java:1168)
	... 4 more

comment:2 Changed 8 years ago by Nicklas Nordborg

Resolution: fixed
Status: newclosed

(In [6509]) Fixes #1828: Calling Directory.getNew() multiple times with overlapping non-existing paths

A thread-local cache of directories that has already been created in the current transaction are used to keep track so that the same directory is not created multiple times.

comment:3 Changed 8 years ago by Nicklas Nordborg

(In [6511]) References #1828: Calling Directory.getNew() multiple times with overlapping non-existing paths

Must clean up the cache also if the transaction is rolled back.

Note: See TracTickets for help on using tickets.