-->
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.  [ 2 posts ] 
Author Message
 Post subject: Parent - Child, self referencing table
PostPosted: Wed Jan 21, 2009 5:45 pm 
Newbie

Joined: Wed Jan 21, 2009 5:24 pm
Posts: 2
Hi, I don't seem to get near a solution, so can someone tell me why this isn't working?

I have a Channel class that looks like this:
Code:
...
@Id
@GeneratedValue(generator = "channel-id")
@GenericGenerator(name = "channel-id", strategy = "increment")
public Long getId() {
   return id;
}
...
@ManyToOne
@JoinColumn(name = "parent")
public Channel getParent() {
   return parent;
}
...
@OneToMany(mappedBy = "parent")
public Set<Channel> getSubchannels() {
   return subchannels;
}
...


And a corresponding JUnit test which is:
Code:
@Before
public void setUp() throws Exception {
   Channel c = new Channel();
   c.setName(CHNAME);
   this.channelDao.create(c);
   
   Channel subc = new Channel();
   subc.setName(SUBCHNAME);
   subc.setParent(c);
   this.channelDao.create(subc);
      
   c = new Channel();
   c.setName(SUBCHNAME + 2);
   c.setParent(subc);
   this.channelDao.create(c);

        c = new Channel();
   c.setName(CHNAME + 2);
   this.channelDao.create(c);
}

public void testGetById() {
   Channel c = this.channelDao.getById(1L);
   assertNotNull(c);
   assertEquals(CHNAME, c.getName());
   assertNull(c.getParent());
   c.getSubchannels();
-->   assertEquals(1, c.getSubchannels().size());
      
   c = this.channelDao.getById(3L);
   assertNotNull(c);
   assertEquals(SUBCHNAME + 2, c.getName());
   assertNotNull(c.getParent());
   assertEquals(2, (long)c.getParent().getId());
}


Unfortunately the subchannels list does not contain any elements. All other asserts pass. Application start up does not give me any errors, the only valuable information I get is:
Code:
Second pass for collection: com.wochs.api.timeframe.model.Channel.subchannels
DEBUG CollectionBinder - Binding a OneToMany: com.wochs.api.timeframe.model.Channel.subchannels through a foreign key
INFO  CollectionBinder - Mapping collection: com.wochs.api.timeframe.model.Channel.subchannels -> channel
DEBUG TableBinder - Retrieving property com.wochs.api.timeframe.model.Channel.parent
DEBUG CollectionSecondPass - Mapped collection key: parent, one-to-many: com.wochs.api.timeframe.model.Channel

which looks totally right for me.
The test database is hsqldb and is created with hibernate.hbm2ddl.auto tool.

Can someone please tell me where I go wrong?[/code]


Top
 Profile  
 
 Post subject: Solved but don't fully understand
PostPosted: Thu Jan 22, 2009 5:57 am 
Newbie

Joined: Wed Jan 21, 2009 5:24 pm
Posts: 2
The problem was something about Transactions.

My getById functions now uses getSession() instead of getHibernateTemplate() (which is spring). Furthermore I test against the subchannels outside the creating transaction like so:
Code:
@Test
@Transactional
@Rollback(false)
public void testGetById() {
   setUp();  <-- create entries manually
   Channel c = this.channelDao.getById(1L);
   assertNotNull(c);
   assertEquals(CHNAME, c.getName());
   assertNull(c.getParent());
   
   c = this.channelDao.getById(3L);
   assertNotNull(c);
   assertEquals(SUBCHNAME + 2, c.getName());
   assertNotNull(c.getParent());
   assertEquals(2, (long)c.getParent().getId());
}

@Test
public void testGetById2() {
   Channel c = this.channelDao.getById(1L);
   assertNotNull(c);
   assertEquals(1, c.getSubchannels().size());
      
   Channel sub = c.getSubchannels().iterator().next();
   assertNotNull(sub);
   assertEquals(1, sub.getSubchannels().size());
   assertEquals(SUBCHNAME, sub.getName());
   assertEquals(1, (long) sub.getParent().getId());
}


Everything works fine this way. Here is my final DAO code:
Code:
@Override
public void create(Channel c) throws DataAccessException {
   Assert.notNull(c, "channel cannot be null");
   
   try {
      getSessionFactory().getCurrentSession().save(c);
   } catch (HibernateException ex) {
      throw convertHibernateAccessException(ex);
   }
}

@Override
public Channel getById(Long id) throws DataAccessException {
   Assert.notNull(id);
   
   try {
      return (Channel) getSession().get(Channel.class, id);
   }catch(HibernateException ex) {
      throw convertHibernateAccessException(ex);
   }
}

Would someone be so kind and confirm that this is an acceptable way of doing it? My intention is, the create method needs to run inside a transaction. Therefore it uses getCurrentSession().
The getById method on the other hand should also be able to run outside of a transaction and uses getSession() therefore, which creates a session if necessary. Is that right?
Why is the collection of subChannels as explained above, not visible inside the creating transaction?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.