-->
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.  [ 1 post ] 
Author Message
 Post subject: put() fails on lazy one-to-many Map
PostPosted: Thu Nov 02, 2006 7:25 am 
Newbie

Joined: Thu Nov 02, 2006 6:20 am
Posts: 2
Hello,

Recently I'm moving my application from Hibernate 3.2.0CR2 to 3.2.0GA, but something's broken.

I have two classes, Document and DocumentHistory.
Document references its history snapshots through a one-to-many Map to DocumentHistory. For performance consideration, the map is lazily loaded.

When I try to add a history to a newly loaded document, it fails:

Code:
Document document = (Document) session.load(Document.class, documentId);
assertNotNull(document);

DocumentHistory history = new DocumentHistory();
history.setVersion(1);
history.setTitle(document.getTitle());
history.setContent(document.getContent());
history.setDocument(document);

// Put the new history into the map.
// !!! The history is not persisted along with the document !!!
Map<Integer, DocumentHistory> histories = document.getHistories();
histories.put(history.getVersion(), history);
// !!! Even histories.size() == 0 at this point !!!
assertEquals(1, histories.size());

document.setTitle("New Title");
document.setContent("New Content");

tx.begin();
session.flush();
tx.commit();


Now I have to add Hibernate.initialize(document.getHistories()) or do some read operation before put() as a work around.

I believe this is a bug of Hibernate 3.2.0GA, because the same test case runs successfully under Hibernate 3.2.0CR2.
Should I report it to JIRA?

Complete test code:

Hibernate version: 3.2.0GA
Hibernate Annotations version: 3.2.0GA
Database: MySQL 5.0.26

DB Script:
Code:
CREATE TABLE `Document` (
  `uuid` char(32) NOT NULL,
  `title` varchar(50) NOT NULL,
  `content` mediumtext NOT NULL,
  PRIMARY KEY  (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `DocumentHistory` (
  `uuid` char(32) NOT NULL,
  `document_uuid` char(32) NOT NULL,
  `version` int(11) NOT NULL,
  `title` varchar(50) NOT NULL,
  `content` mediumtext NOT NULL,
  PRIMARY KEY  (`uuid`),
  KEY `document_uuid` (`document_uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


Annotated classes:
Code:
@Entity
public class Document implements Serializable {
   private String uuid;
   private String title;
   private String content;
   private Map<Integer, DocumentHistory> histories = new HashMap<Integer, DocumentHistory>();

   @Id @GeneratedValue(generator = "system-uuid")
      @GenericGenerator(name = "system-uuid", strategy = "uuid")
   public String getUuid() {
      return uuid;
   }
   public void setUuid(String uuid) {
      this.uuid = uuid;
   }

   @Column(name = "title", length = 50)
   public String getTitle() {
      return title;
   }
   public void setTitle(String title) {
      this.title = title;
   }

   @Basic(fetch = FetchType.LAZY)
   @Column(name = "content", nullable = false)
   @Lob
   public String getContent() {
      return content;
   }
   public void setContent(String content) {
      this.content = content;
   }

   @OneToMany(mappedBy = "document", fetch = FetchType.LAZY,
         cascade = {CascadeType.ALL})
   @MapKey(name = "version")
   public Map<Integer, DocumentHistory> getHistories() {
      return this.histories;
   }
   public void setHistories(Map<Integer, DocumentHistory> histories) {
      this.histories = histories;
   }
}


Code:
@Entity
public class DocumentHistory implements Serializable {
   private static final long serialVersionUID = 1L;

   private String uuid;
   private int version;
   private String title;
   private String content;
   private Document document;

   @Id @GeneratedValue(generator = "system-uuid")
      @GenericGenerator(name = "system-uuid", strategy = "uuid")
   public String getUuid() {
      return uuid;
   }
   public void setUuid(String uuid) {
      this.uuid = uuid;
   }

   @Column(name = "version", nullable = false, updatable = false)
   public int getVersion() {
      return version;
   }
   public void setVersion(int version) {
      this.version = version;
   }

   @Column(name = "title", length = 50)
   public String getTitle() {
      return title;
   }
   public void setTitle(String title) {
      this.title = title;
   }

   @Basic(fetch = FetchType.LAZY)
   @Column(name = "content", nullable = false)
   @Lob
   public String getContent() {
      return content;
   }
   public void setContent(String content) {
      this.content = content;
   }

   @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "document_uuid", nullable = false, updatable = false)
   public Document getDocument() {
      return document;
   }
   public void setDocument(Document document) {
      this.document = document;
   }
}


JUnit test case:
Code:
public class HibernateMapTest extends TestCase {
   private Session session;
   private String documentId;

   @Override
   protected void setUp() throws Exception {
      AnnotationConfiguration cfg = new AnnotationConfiguration();
      cfg.addAnnotatedClass(Document.class);
      cfg.addAnnotatedClass(DocumentHistory.class);
      cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
      cfg.setProperty("hibernate.connection.url", "jdbc:mysql://192.168.11.1/sample");
      cfg.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
      cfg.setProperty("hibernate.connection.username", "*****");
      cfg.setProperty("hibernate.connection.password", "*****");
      cfg.setProperty("hibernate.show_sql", "true");

      SessionFactory sf = cfg.buildSessionFactory();

      session = sf.openSession();
      // Create a document
      Transaction tx = session.beginTransaction();
      Document document = new Document();
      document.setTitle("Title");
      document.setContent("Content");

      documentId = (String) session.save(document);
      tx.commit();
      // Kicks it out of the session cache
      session.evict(document);
   }

   @Override
   protected void tearDown() throws Exception {
      if (session != null && session.isOpen()) {
         Transaction tx = session.getTransaction();
         try {
            // DB Clean-up
            Document document = (Document) session.get(Document.class, documentId);
            if (document != null) {
               tx.begin();
               session.delete(document);
               tx.commit();
            }
         } catch (HibernateException ex) {
            if (tx.isActive())
               tx.rollback();
         } finally {
            try {
               session.close();
               session = null;
            }
            catch (Throwable e) {
            }
         }
      }
   }

   public void testHistory1() throws Exception {
      Transaction tx = session.getTransaction();
      try {
         // Load it...
         Document document = (Document) session.load(Document.class, documentId);
         assertNotNull(document);

         DocumentHistory history = new DocumentHistory();
         history.setVersion(1);
         history.setTitle(document.getTitle());
         history.setContent(document.getContent());
         history.setDocument(document);

         // Put the new history into the map.
         // !!! The history is not persisted along with the document !!!
         Map<Integer, DocumentHistory> histories = document.getHistories();
         histories.put(history.getVersion(), history);
         // !!! Even histories.size() == 0 at this point !!!
         // assertEquals(1, histories.size());

         document.setTitle("New Title");
         document.setContent("New Content");

         tx.begin();
         session.flush();
         tx.commit();
         session.evict(document);

         // And load it agian...
         document = (Document) session.load(Document.class, documentId);
         assertNotNull(document);
         // Check if the DocumentHistory object persisted correctly...
         assertEquals(1, document.getHistories().size());
      } catch (HibernateException ex) {
         fail(ex.toString());
         tx.rollback();
      }
   }
}


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

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.