Hibernate version: Hibernate Annotations 3.3.1.GA, Hibernate 3.2.6, Hibernate EntityManager 3.3.2.GA
Hi,
I'm trying to use @CollectionOfElements to map some name-value string pairs in a Map. It is saving out correctly, but does not read back in correctly. I'd greatly appreciate any insight into if I've done something wrong here or if this looks like a bug. I've tried it both on Oracle & Postgres databases, and it makes no diff.
The mapped class:
Code:
import java.util.HashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
import org.hibernate.annotations.CollectionOfElements;
import org.hibernate.annotations.MapKey;
....
@Entity
@Table(name = "job")
public class Job {
....
@CollectionOfElements()
@JoinTable(name = "job_parameters", joinColumns = { @JoinColumn(name = "job_id") })
@MapKey(columns = { @Column(name = "name") })
@Column(name = "value")
private Map<String, String> mParameters = new HashMap<String, String>();
public Map<String, String> getParameters() {
return mParameters;
}
public void setParameters(Map<String, String> parameters) {
mParameters = parameters;
}
}
The table of interest:
Code:
create table job_parameters(UUID job_id, name varchar(256), value varchar(4000));
Code that demos the problem:
Code:
public class BugTest extends AbstractTransactionalTestNGSpringContextTests {
@PersistenceContext
protected EntityManager mEntityManager;
@Test(groups = { "functional" })
public void bugtest() {
Job j = new Job();
j.getParameters().put("Test flag", "true");
mJobDao.save(j);
mEntityManager.flush();
mEntityManager.refresh(j);
System.out.println("NUMBER OF PARAMETERS: " + j.getParameters().keySet().size());
}
}
The problem:
I've verified that the job parameters are written out correctly (and the log shows this as well), but when the object is refreshed (or just read in in a new session, where I'm really running into this issue), the data comes in from the db (see the log below with the values printed out), but does not actually get set in the Job.mParameters map.
Log:
Code:
...
14:09:02.246 [1] INFO o.h.c.a.Version: Hibernate Annotations 3.3.1.GA
14:09:02.262 [1] INFO o.h.c.Environment: Hibernate 3.2.6
14:09:02.277 [1] INFO o.h.c.Environment: hibernate.properties not found
14:09:02.277 [1] INFO o.h.c.Environment: Bytecode provider name : cglib
14:09:02.277 [1] INFO o.h.c.Environment: using JDK 1.4 java.sql.Timestamp handling
14:09:02.356 [1] INFO o.h.e.Version: Hibernate EntityManager 3.3.2.GA
14:09:02.387 [1] INFO o.h.e.Ejb3Configuration: Processing PersistenceUnitInfo [
name: DefaultPersistenceUnit
...]
...
14:09:05.199 [1] INFO o.s.t.c.t.TransactionalTestExecutionListener: Began transaction (1): transaction manager [org.springframework.orm.jpa.JpaTransactionManager@174f02c]; rollback [true]
14:09:05.262 [1] DEBUG o.h.SQL: insert into job (executor_instance, can_be_rerun, executor_class, insert_tm, priority, queue_tm, start_tm, type_name, weight, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
14:09:05.277 [1] TRACE o.h.t.StringType: binding null to parameter: 1
14:09:05.277 [1] TRACE o.h.t.BooleanType: binding 'true' to parameter: 2
14:09:05.277 [1] TRACE o.h.t.ClassType: binding 'com.foo.job.dbbacked.TestHelper$TestJobExecutor' to parameter: 3
14:09:05.277 [1] TRACE o.h.t.TimestampType: binding '2008-08-11 14:09:05' to parameter: 4
14:09:05.277 [1] TRACE o.h.t.IntegerType: binding '5' to parameter: 5
14:09:05.277 [1] TRACE o.h.t.TimestampType: binding null to parameter: 6
14:09:05.277 [1] TRACE o.h.t.TimestampType: binding null to parameter: 7
14:09:05.277 [1] TRACE o.h.t.StringType: binding 'com.foo.job.dbbacked.TestHelper$TestJobType' to parameter: 8
14:09:05.277 [1] TRACE o.h.t.IntegerType: binding '30' to parameter: 9
14:09:05.277 [1] DEBUG o.h.SQL: insert into job_parameters (job_id, name, value) values (?, ?, ?)
14:09:05.277 [1] TRACE o.h.t.StringType: binding 'Test flag' to parameter: 2
14:09:05.277 [1] TRACE o.h.t.StringType: binding 'true' to parameter: 3
14:09:05.293 [1] DEBUG o.h.SQL: select job0_.id as id4_0_, job0_.executor_instance as executor2_4_0_, job0_.can_be_rerun as can3_4_0_, job0_.executor_class as executor4_4_0_, job0_.insert_tm as insert5_4_0_, job0_.priority as priority4_0_, job0_.queue_tm as queue7_4_0_, job0_.start_tm as start8_4_0_, job0_.type_name as type9_4_0_, job0_.weight as weight4_0_ from job job0_ where job0_.id=?
14:09:05.309 [1] TRACE o.h.t.StringType: returning null as column: executor2_4_0_
14:09:05.309 [1] TRACE o.h.t.BooleanType: returning 'true' as column: can3_4_0_
14:09:05.309 [1] TRACE o.h.t.ClassType: returning 'com.foo.job.dbbacked.TestHelper$TestJobExecutor' as column: executor4_4_0_
14:09:05.309 [1] TRACE o.h.t.TimestampType: returning '2008-08-11 14:09:05' as column: insert5_4_0_
14:09:05.309 [1] TRACE o.h.t.IntegerType: returning '5' as column: priority4_0_
14:09:05.309 [1] TRACE o.h.t.TimestampType: returning null as column: queue7_4_0_
14:09:05.309 [1] TRACE o.h.t.TimestampType: returning null as column: start8_4_0_
14:09:05.309 [1] TRACE o.h.t.StringType: returning 'com.foo.job.dbbacked.TestHelper$TestJobType' as column: type9_4_0_
14:09:05.309 [1] TRACE o.h.t.IntegerType: returning '30' as column: weight4_0_
14:09:05.324 [1] DEBUG o.h.SQL: select mparameter0_.job_id as job1_0_, mparameter0_.value as value0_, mparameter0_.name as name0_ from job_parameters mparameter0_ where mparameter0_.job_id=?
14:09:05.340 [1] TRACE o.h.t.StringType: returning 'true' as column: value0_
14:09:05.340 [1] TRACE o.h.t.StringType: returning 'Test flag' as column: name0_
NUMBER OF PARAMETERS: 0
You can see from the insert that it does indeed insert the job_parameters table, and you can even see that on the refresh it's returning 'true' and 'Test flag' as it should. However, as you can see from the log, it thinks it has nothing in the Map. I've tried adding the following annotations / modifications one by one and in various combinations on the member variable, and they have no effect on this issue (still written out correctly, apparently read in from the db, but not set in the Map):
Code:
@CollectionOfElements(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@BatchSize(size = 60)
Can anyone see if I'm doing anything wrong, or have insight as to whether this might be a bug?
Thanks much in advance,
Greg