• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Need some feedback about "Harnessing Hibernate"

 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am currently going though the above mentioned book by James Elliot and after going through a couple of chapters I am feeling a little frustrated due to lack of precise or complete explanation.

I was first alarmed in Section 4.1.1 where TRACK_ARTIST table and INVERSE attribute is introduced. It says, " In the case of a many-to-many association like this one, the choice of which side to call the inverse mapping isn't crucial, although it does affect when Hibernate will decide to automatically update the join table. The fact that the join table is named "track artists" makes the link from artists back to tracks the best choice for the inverse end, if only from the perspective of people trying to understand the database."

Here I was actually expecting an answer to a very obvious question that what is the criteria to decide which one should be the inverse end. Obviously, hibernate doesn't care which one. But I as the designer of the project do and I need help in deciding which one should be made inverse. May be there is no rule, but there's got to be some convention, some best practice. I can't just toss a coin to decide. Saying that it isn't crutial sounds avasive to me.

Then in section 4.2.1, method addTrackArtist(Track, Artist) is introduced. There is only one line of code it this method - track.getArtists().add(artist);
Now, I am completely confused about why this method is needed. First, the method name does not convey whether it is adding Tracks to an Artist or the reverse. Second, why should I use this method instead of directly calling track.getArtists().add(artist); Is there a difference? Should I always wrap such addition into wrapper methods like this? Does it have any relation to the inverse attribute that we saw earlier? These are some important questions in my mind and they are completely left unanswered.

Now, I am wondering whether these and such other questions are answered later in the book? Will the picture be clear after I finish reading the book or should I just skip this book and find another one.

I would really appreciate any comments from folks who have read this book.

thank you,
Ann
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ann Basso wrote:I was first alarmed in Section 4.1.1 where TRACK_ARTIST table and INVERSE attribute is introduced. It says, " In the case of a many-to-many association like this one, the choice of which side to call the inverse mapping isn't crucial, although it does affect when Hibernate will decide to automatically update the join table. The fact that the join table is named "track artists" makes the link from artists back to tracks the best choice for the inverse end, if only from the perspective of people trying to understand the database."

Here I was actually expecting an answer to a very obvious question that what is the criteria to decide which one should be the inverse end. Obviously, hibernate doesn't care which one. But I as the designer of the project do and I need help in deciding which one should be made inverse. May be there is no rule, but there's got to be some convention, some best practice. I can't just toss a coin to decide. Saying that it isn't crutial [sic] sounds avasive [sic] to me.

Well, the text tells you one of the potential technical differences, and provides another non-technical (design comprehension) reason why to do it one particular way.

The Hibernate documentation goes in to more detail (you *are* referring to the Hibernate documentation and the web, and not just this book, I hope?) and will also help you decide on which end to put the "inverse" based on circumstances. A trivial Google search turns up a *lot* of ancillary information, including:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html
http://itefforts.blogspot.com/2007/10/understanding-mapping-attribute.html
http://tadtech.blogspot.com/2007/02/hibernate-when-is-inversetrue-and-when.html

Where to put an "inverse" depends on your needs--and it *isn't* always crucial.

Ann Basso wrote:Then in section 4.2.1, method addTrackArtist(Track, Artist) is introduced. There is only one line of code it this method - track.getArtists().add(artist);Now, I am completely confused about why this method is needed. First, the method name does not convey whether it is adding Tracks to an Artist or the reverse.

To me, the name conveys what it does, although I suppose that's debatable--but the name of this method seems a rather minor detail. If it helps you, perhaps you could rename yours to addArtistToTrack(Artist) or something? Or if it's in the Track class, simply addArtist(Artist)

Ann Basso wrote:Second, why should I use this method instead of directly calling track.getArtists().add(artist); Is there a difference?

Is there a difference in what way? Functionally? Of course not--the code works the same way whether you call it directly or call it via a method. If you're asking about a functional difference a Java refresher might be appropriate.

Cognitively? Sure, although if the method name is unclear to you, the cognitive overhead might actually be worse. If it was named something that was more clear to you, then yes, it's a reasonable refactoring, and may expose less of the internal implementation to the outside world. Whether or not you care about that is a different issue, and unrelated to ORM.

Ann Basso wrote:Should I always wrap such addition into wrapper methods like this?

"Should" implies a level of obligation I am uncomfortable with, and this question is also unrelated to ORM--it's a design/ refactoring question. Nonetheless, my answer would be "It depends."

Ann Basso wrote:Does it have any relation to the inverse attribute that we saw earlier?

No--the code is (hopefully obviously) functionally equivalent whether called directly or from a method.

Ann Basso wrote:These are some important questions in my mind and they are completely left unanswered.

The "inverse" question is reasonable, the single-line method question is valid, but you seem unusually focused on it.
 
Jaikiran Pai
Marshal
Pie
Posts: 10447
227
IntelliJ IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here I was actually expecting an answer to a very obvious question that what is the criteria to decide which one should be the inverse end. Obviously, hibernate doesn't care which one. But I as the designer of the project do and I need help in deciding which one should be made inverse. May be there is no rule, but there's got to be some convention, some best practice. I can't just toss a coin to decide. Saying that it isn't crutial sounds avasive to me.


Probably, this might help.
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello David,
Thank you very much for responding.

David Newton wrote:
Ann Basso wrote:I was first alarmed in Section 4.1.1 where TRACK_ARTIST table and INVERSE attribute is introduced. It says, " In the case of a many-to-many association like this one, the choice of which side to call the inverse mapping isn't crucial, although it does affect when Hibernate will decide to automatically update the join table. The fact that the join table is named "track artists" makes the link from artists back to tracks the best choice for the inverse end, if only from the perspective of people trying to understand the database."

Here I was actually expecting an answer to a very obvious question that what is the criteria to decide which one should be the inverse end. Obviously, hibernate doesn't care which one. But I as the designer of the project do and I need help in deciding which one should be made inverse. May be there is no rule, but there's got to be some convention, some best practice. I can't just toss a coin to decide. Saying that it isn't crucial sounds avasive to me. (*Fixed my spelling errors*)

Well, the text tells you one of the potential technical differences, and provides another non-technical (design comprehension) reason why to do it one particular way.

May be I am unable to understand it properly but I don't know what technical difference is being pointed out. It just says it "affects when Hibernate will decide to automatically update the join table" but it doesn't really tell the difference. How does it affect?

David Newton wrote:
The Hibernate documentation goes in to more detail (you *are* referring to the Hibernate documentation and the web, and not just this book, I hope?)

Do I have a choice ?



I respectfully disagree with the applicability of your suggestion of google search. Obviously, one can find all the information on the internet. Then what is the need for buying a book. I can understand the need to refer to the manuals for API references or some specific situation, error message etc. but I expect a book to provide answers to conceptual things like this.

David Newton wrote:
Where to put an "inverse" depends on your needs--and it *isn't* always crucial.

That's exactly what I am asking. What kind of "need" determines where to put inverse? Every decision depends on needs. Even decision to use Hibernate depends on needs. The statement "it depends on your needs" is essentially redundant. May be my confusion is too elementry.

David Newton wrote:
Ann Basso wrote:Then in section 4.2.1, method addTrackArtist(Track, Artist) is introduced. There is only one line of code it this method - track.getArtists().add(artist);Now, I am completely confused about why this method is needed. First, the method name does not convey whether it is adding Tracks to an Artist or the reverse.

To me, the name conveys what it does, although I suppose that's debatable--but the name of this method seems a rather minor detail. If it helps you, perhaps you could rename yours to addArtistToTrack(Artist) or something? Or if it's in the Track class, simply addArtist(Artist)

Ann Basso wrote:Second, why should I use this method instead of directly calling track.getArtists().add(artist); Is there a difference?

Is there a difference in what way? Functionally? Of course not--the code works the same way whether you call it directly or call it via a method. If you're asking about a functional difference a Java refresher might be appropriate.

Cognitively? Sure, although if the method name is unclear to you, the cognitive overhead might actually be worse. If it was named something that was more clear to you, then yes, it's a reasonable refactoring, and may expose less of the internal implementation to the outside world. Whether or not you care about that is a different issue, and unrelated to ORM.

Ann Basso wrote:Should I always wrap such addition into wrapper methods like this?

"Should" implies a level of obligation I am uncomfortable with, and this question is also unrelated to ORM--it's a design/ refactoring question. Nonetheless, my answer would be "It depends."

Ann Basso wrote:Does it have any relation to the inverse attribute that we saw earlier?

No--the code is (hopefully obviously) functionally equivalent whether called directly or from a method.

Ann Basso wrote:These are some important questions in my mind and they are completely left unanswered.

The "inverse" question is reasonable, the single-line method question is valid, but you seem unusually focused on it.


I think you may be missing the point. The code given in the book is there to explain a concept. A novice/beginner (such as myself) will seriously think about whatever is written as being important to the concept being explained. Every thing in the book subconciously affects the reader. That's why every piece of code should follow proper coventions and should be according to best practices. At least I assume that the writer has done that (followed conventions and best practices) and so I assume that every line of code presented in the book is there for a reason. May be you are an expert and so you can easily filter out whatever is not relevant or is just a matter of style. But I am unable to do so because I am not an expert. If the method in question is not serving any purpose (w.r.t. the concept being explained), it should not have been there in the first place. Since it is there, I was thinking may be that's the way it should be done and I was left wondering why.


thank you!

 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jaikiran Pai wrote:
Here I was actually expecting an answer to a very obvious question that what is the criteria to decide which one should be the inverse end. Obviously, hibernate doesn't care which one. But I as the designer of the project do and I need help in deciding which one should be made inverse. May be there is no rule, but there's got to be some convention, some best practice. I can't just toss a coin to decide. Saying that it isn't crutial sounds avasive to me.


Probably, this might help.


Thank you, Jaikiran! That was very helpful.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The second one where it adds to the other side collection. That is because it is best practice in bi-directional associations to set both sides. Meaning if I add something to one side's collection, I should at the same time add it to the other collection.

Why? Because if you have it on one side, it might, and I add it might just insert into the join table from one side, then delete it from the join table on the other side. And this is where having your inverse="true" in ManyToMany might come into play. I say might, because I haven't tried it out to see what happens because I always set both sides in a bi-directional association in Java code, in all associations that might be bi-directional.

But for ManyToMany, inverse=true can be on either side, it doesn't matter from the standpoint that it works on both. And if you set both sides in any call to setting one side in Java, then it really doesn't matter the order, it will always end up looking the same. But if you don't set both sides, then there is a small reprocussion that could occur.

Mark
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's why every piece of code should follow proper coventions and should be according to best practices. At least I assume that the writer has done that (followed conventions and best practices) and so I assume that every line of code presented in the book is there for a reason.

Book code almost *never* follows "best practices" -- that would be too much cognitive overhead. Best practices would include layers of abstraction that would take away from the basic points being illustrated. "Proper conventions" is a meaningless phrase, since what is "proper" varies wildly across people, organizations, and so on--a simple refactoring like the one you're obsessing about simply isn't worth the effort.

Maybe you just haven't read very many programming books--that's fine, but be aware that book code is often wrong on many levels, doesn't necessarily represent any sort of best practices, can't possibly answer every question that could be asked, and is usually out-of-date before the final draft is approved. That is the nature of books. That is why online documentation *must* be used alongside *any* hardcopy material.
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark Spritzler wrote:The second one where it adds to the other side collection. That is because it is best practice in bi-directional associations to set both sides. Meaning if I add something to one side's collection, I should at the same time add it to the other collection.

Why? Because if you have it on one side, it might, and I add it might just insert into the join table from one side, then delete it from the join table on the other side. And this is where having your inverse="true" in ManyToMany might come into play. I say might, because I haven't tried it out to see what happens because I always set both sides in a bi-directional association in Java code, in all associations that might be bi-directional.

But for ManyToMany, inverse=true can be on either side, it doesn't matter from the standpoint that it works on both. And if you set both sides in any call to setting one side in Java, then it really doesn't matter the order, it will always end up looking the same. But if you don't set both sides, then there is a small reprocussion that could occur.

Mark

Thank you! That was the kind of explanation I was expecting in the book. I believe the expectation is justified.
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David Newton wrote:
That's why every piece of code should follow proper coventions and should be according to best practices. At least I assume that the writer has done that (followed conventions and best practices) and so I assume that every line of code presented in the book is there for a reason.

Book code almost *never* follows "best practices" -- that would be too much cognitive overhead. Best practices would include layers of abstraction that would take away from the basic points being illustrated. "Proper conventions" is a meaningless phrase, since what is "proper" varies wildly across people, organizations, and so on--a simple refactoring like the one you're obsessing about simply isn't worth the effort.

Maybe you just haven't read very many programming books--that's fine, but be aware that book code is often wrong on many levels, doesn't necessarily represent any sort of best practices, can't possibly answer every question that could be asked, and is usually out-of-date before the final draft is approved. That is the nature of books. That is why online documentation *must* be used alongside *any* hardcopy material.


Yes, may be I haven't read very many programming books. Even so, I absolutely totally disagree with your view. Quality authors realize that what they write in the book is what will be followed by the reader and they take efforts to make sure what they are writing follows best practices and conventions within the bounds of reasonability. If a beginners book on java (or for that matter any Java book) presents a HelloWorld class named as helloWorld, I would question the quality of the book even if the name of the class has nothing to do with the concept being presented.

May be that's why some books are elevated to the status of bible for something while some books gather dust in book shelves.


BTW, I forgot to mention source of confusion in addTrackArtist method in my previous reply to you. Code for this method is given as:

From the method name, I thought that Track is to be added to Artist. But the code shows that Artist is being added to Track. (How can some one interpret addTrackArtist as addArtistToTrack is beyond me.) This certainly has a relation with the inverse attribute as Mark explained. If this is not crappy writing, what is??

 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David Newton wrote:
Maybe you just haven't read very many programming books--


I am wondering if the statement like above is acceptable at JavaRanch. I remember reading sometime back that anything that implies that a JavaRanch member is less than perfect is a violation of "be nice" rule :)
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ann Basso wrote:
David Newton wrote:
Maybe you just haven't read very many programming books--


I am wondering if the statement like above is acceptable at JavaRanch. I remember reading sometime back that anything that implies that a JavaRanch member is less than perfect is a violation of "be nice" rule :)


If it is David, I'll slap him on the wrist at the next bartender's meeting.

Mark
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ann Basso wrote: (How can some one interpret addTrackArtist as addArtistToTrack is beyond me.)

It might be "beyond you", but that shouldn't imply that your interpretation is the only possible one. When I see "addTrackArtist" I interpret as adding a track artist. A track artist is an artist that worked on the track. I still don't understand why you're so incensed by this method name, but okay.

There are *very* few programming books that contain perfect code, perfect explanations, perfect anything. People that haven't read a lot of programming books may not have had the time to realize just how many mistakes there are in even the most carefully-produced books. That you're so bothered by what you perceive to be gross negligence and unintelligible code lead me to believe you haven't read many programming books, and I suggested as much. While I don't really understand *why* you'd be offended by that suggestion, I feel badly that you were, as no offense was intended.
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
David Newton wrote:
Ann Basso wrote: (How can some one interpret addTrackArtist as addArtistToTrack is beyond me.)

It might be "beyond you", but that shouldn't imply that your interpretation is the only possible one. When I see "addTrackArtist" I interpret as adding a track artist. A track artist is an artist that worked on the track. I still don't understand why you're so incensed by this method name, but okay.

Ok, I see your point. I really did not get that earlier. Since the class is name Artist, I didn't think of "track artist" as an entity. I was really troubled with it because it took me a lot of time to figure out what is he trying to do and to establish a relation between inverse attribute and the way add method is coded. I really do believe that the author should outthink the reader and provide answers.


There are *very* few programming books that contain perfect code, perfect explanations, perfect anything. People that haven't read a lot of programming books may not have had the time to realize just how many mistakes there are in even the most carefully-produced books. That you're so bothered by what you perceive to be gross negligence and unintelligible code lead me to believe you haven't read many programming books, and I suggested as much. While I don't really understand *why* you'd be offended by that suggestion, I feel badly that you were, as no offense was intended.

There are several things here.
1. It's not about being perfect. I realize there may be mistakes. But there is a difference between mistakes and omissions. Mistakes/typos, I can understand. Even conscious omission (e.g. we will not deal with this issue in this book) is understandable because at least the reader knows that if he is interested he has to look somewhere else. But skipping over an important thing entirely is bad. Omissions tell me that the author doesn't know what needs to be told in the book.

2. Yes, there are lot of IT books that have tons of mistakes in many books. But that doesn't mean we have to accept that the quality of books will be lower for every book. Just because there are 90% bad movies doesn't mean we have to spend money on a bad movie.

3. I believe things like these differentiate between good and bad books. I have limited time, I want to spend it on a book with the most ROI. For example, I got hold of Java persistence with Hibernate, and the difference is stark. I had a similar (good) experience with Thinking in Java, which I got hold of after reading some other Java books, and with a book on EJB by Richard Monson Haefel (I forgot the name). There are many others.

4. Peace.

The bottom line is, I should have pickup up JPWH in the first place.
 
Ann Basso
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very sorry, I again forgot to add another point regarding why I was so incensed over the addTrackArtist method (and now I am unable to edit the post) and why I could not interpret it as add"track artist".
This method is static and is presented out side of Track as well as Artist classes. So that led me to the interpretation addTrackToArtist instead of add"track artist". A static method addArtist (as in the interpretation add"track artist") would indeed be bad naming as it does not tell me what the method is supposed to do. Because an artist may be added to a track using track.add approach as well as artist.setTrack approach.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic