Win a copy of Android Programming: The Big Nerd Ranch Guide this week in the Android forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Simple JPA OneToMany Example  RSS feed

 
Kiri Eda
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I wish to create a simple example of a one to many mapping with
field access -- not property access.
The annotations should be on the attributes, not methods.
The 'many' side should have a foreign key which points to the @Id of the 'one' side.
The example I made constructs the database correctly, however the Java code does not see the data as desired.

As you can see, the list is empty at the comment,

//Error seen here.

Please, tell us what is wrong or show us what is correct and we will have a good, simple example of OneToMany.

The code is at
https://gitgud.io/Kiri/OneToMany
 
Roel De Nijs
Sheriff
Posts: 11200
174
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Kiri Eda,

First of all, a warm welcome to CodeRanch!

Kiri Eda wrote:Please, tell us what is wrong or show us what is correct and we will have a good, simple example of OneToMany.

It's very unlikely you'll get any helpful replies with such a post. It does provide information about what you are trying to do (which is very good). But you don't provide any details about your code. You simply provide a link and tell us to go to that link for the code. So the more effort and time I (and probably many others) have to spend to find the code and the issue, the less time I can spend on creating a helpful reply. So I (and many others) will just skip this topic because it's too much effort and work to find the error/issue. You should definitely read HowToAskQuestionsOnJavaRanch first. It contains a bunch of guide lines about how to ask questions effectively (e.g. The more information you provide, the easier it is for people to answer your questions.)

It would be much better to post the relevant code in your post (using code tags). So you should not copy/paste all your code into a post, because nobody will go through 100+ lines of code to find the issue (again for the same reason: it consumes way too much time from anyone's free/spare time). So you should simply create a new post with a SSCCE (using code tags) and provide as much details as possible (which records are in database, which queries are executed, which information is returned by the queries, which information you were expecting, and so on).

And finally, a little bit of help about your actual issue. Whenever I have an issue with JPA, I always have a look at the Java Persistence WikiBook. It's really an awesome and excellent resource which has already solved many of my issues. Besides great explanations, it also provides code examples for almost every topic. You'll find the section about the OneToMany relationship here.

Hope it helps!
Kind regards,
Roel
 
Kiri Eda
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I had already read the documentation at Wikibooks and Oracle, among others.

There are a few variations. Here is one used at Wikibooks.
It is bidirectional.

Given classes Many and One.

In main(),

getMany() returns null , so this results in an error calling add().
 
Roel De Nijs
Sheriff
Posts: 11200
174
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kiri Eda wrote:getMany() returns null , so this results in an error calling add().

That makes sense as the instance variable many is not initialized at all. So if you create a new One instance, many will be null. That's not really related to a JPA issue. Unless you are retrieving a One instance from the database with Many children and this collection is not populated for some reason. But that's not really clear from your explanation.
 
Kiri Eda
Greenhorn
Posts: 6
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In response to the last message, I tried initializing the Set<> many. The result does not work. Entries are not made in the foreign key field.
I expect JPA to handle the data structure itself, and that one does not need to provide an instance of a RAM/main-memory based datastructure.
I expect it to handle that with field access, as it does with property access.

The best way to make everything clear to people who wish to avoid viewing the code at the link I provided is to show it here, so I do.

The Many objects linked to a One should be retrievable by a OneToMany relationship.

I've tried different variations with @JoinColumn fields and parameters to @OneToMany. This is only 1 of them.

Many.java


One.java


Main
 
Roel De Nijs
Sheriff
Posts: 11200
174
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kiri Eda wrote:In response to the last message, I tried initializing the Set<> many. The result does not work. Entries are not made in the foreign key field.
I expect JPA to handle the data structure itself, and that one does not need to provide an instance of a RAM/main-memory based datastructure.
I expect it to handle that with field access, as it does with property access.

You have very high expectations about JPA

As the relationship is bi-directional so as the application updates one side of the relationship, the other side should also get updated, and be in sync. In JPA, as in Java in general it is the responsibility of the application, or the object model to maintain relationships. If your application adds to one side of a relationship, then it must add to the other side.
 
Kiri Eda
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This Wikibooks entry describes exactly what I am trying to do (most of all):

Unidirectional OneToMany, No Inverse ManyToOne, No Join Table

I implemented it exactly as described there (as 1 variation). I also initialize the Set with a HashSet in the default constructor.






If it is changed as the error states it should,



then a different error occurs.
 
Roel De Nijs
Sheriff
Posts: 11200
174
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kiri Eda wrote:then a different error occurs.

And which error does occur? Please always TellTheDetails.

And based on the code example from the Java Persistence WikiBook you have linked to, it seems your mapping is still bidirectional as the code example uses a field to store the owner id (and not an entity like in your example).
 
Kiri Eda
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So that I could report what the error was, I arranged the code as I did before -- or I intended to. With

. I also completely erased the database and created it again. Then it worked as desired. I have only tested inserts so far.

The ONE in being referred to in the code is the column in table MANY named ONE -- not the table named ONE.

The next step is to make it bidirectional with the owning side as the 'one' side. I only see a way to have JPA consider the Many as owner. However, the code can be written so that to outside users, it works as if the One class is owner of the relationship.

It seems that for the bidirectional relationship it is necessary to either hide the Set from outside users and only permit adding and removing with a method of One or creating a new Set class which calls methods of Many to change the relationship. That appears to be substantially difficult since all methods of Set must be implemented and an Iterator provided.
 
Roel De Nijs
Sheriff
Posts: 11200
174
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kiri Eda wrote:It seems that for the bidirectional relationship it is necessary to either hide the Set from outside users and only permit adding and removing with a method of One or creating a new Set class which calls methods of Many to change the relationship. That appears to be substantially difficult since all methods of Set must be implemented and an Iterator provided.

Indeed! That's also a very good design practice because you will be hiding implementation details using add/remove methods. And it's also very convenient. The code required to maintain the model is handled in one place (method) and thus the developer doesn't need to worry about it and can simply invoke the add or remove methods.

A typical method to add a Many instance looks likeAnd the code to remove a Many instance is very similar: you set one to null and remove the instance from the collection. That's very common code when you are using a bi-directional mapping.

Hope it helps!
Kind regards,
Roel
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!