jpa OneToMany & ManyToOne - jpa

i have a oneToMany and ManyToOne mapping in my models:
class User
#OneToMany (cascade = { CascadeType.REFRESH, CascadeType.DETACH }, fetch = FetchType.EAGER)
private Set<Judgement> judgements;
class Judgement
#ManyToOne(cascade = { CascadeType.REFRESH, CascadeType.DETACH})
#JoinColumn(name = "user_id")
private User judge;
and in DB, i have to tables as Users and Judgements, when i tried to run my code, it showed error as:
Caused by: org.postgresql.util.PSQLException: ERROR: relation "users_judgements" does not exist
does that mean i have to create the table users_judgements by hand, jpa cannot automatically create the relationship for me? RoR can do it...Thanks.

If you have a foreign key from USER table, user_id, in JUDGMENT table then there is no need to have another table. That will be the #JoinColumn(name = "user_id").
See if you are missing something; I can not see any "mappedBy" attribute, which will be "user" in your case.
Please take a look at this article; page 4 that the link will take you, give details about one-to-many relationship. It will be worth reading the whole article.
http://www.javaworld.com/javaworld/jw-01-2008/jw-01-jpa2.html?page=4
Also, the part 1 of the same tutorial is good for basics;
http://www.javaworld.com/javaworld/jw-01-2008/jw-01-jpa1.html

Related

JPA one-to-one bidirectional mapping on same object using association table

I have a table Person and now I want to express a relation like "best friend". Assuming a person can only have one best friend I don't want to alter the Person table to add a best friend column, rather I want to have an additional mapping table, e.g.:
Table Person (id name):
1 foo
2 bar
3 somebody
4 somebodyelse
Table BestFriendMapping (personId bestfriendId):
1 2
3 4
I was doing something like this:
class Person {
#OneToOne()
#Fetch(FetchMode.SELECT)
#JoinTable(name = "BestFriendMapping",
joinColumns = #JoinColumn(name = "personId", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "bestfriendId",
referencedColumnName = "id"))
private Person bestFriend;
}
The problem is, that now when I add a new Person, the mapping table is populated with two entries, for example the newly added Person is having id=10 and his bestFriend 20, then the entries are:
10 20
20 10
I would like to have just one entry, but still be able to get the best friend of a person no matter which I have in my hand currently. I found out that I probably have done two unidirectional instead of one bi-directional mapping, so I have to use mappedBy, but I am not sure what is the syntax when it is about the one and the same entity object, thus one and the same field inside the object. The examples on the internet are always showing the mapping of two entities via a mapping table.
Or maybe something like this?!? In addition to the JoinColumns and InverseJoinColumns to add mappedBy to the OnetoOne just like this #OneToOne(mappedBy="bestFriend"), kind of weird :)

JaVers, SpringDatat, JPA: Querying for Entity Update inside a Collection

I'm new to Stackoverflow, so I will make my best to conforms with usage. I was wondering if there were a way to get a complete list of changes/snapshots of a given Entity. For now it works well with edition of Singular Properties, as well as Addition and Deletion to Collection Property. But I'm unable to find when a Child Entity in the Collection Property was updated.
Given two Entities, and a LinkEntity:
#Entity
class Person {
#Id
Long id;
#OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
Set<LinkAddress> addresses;
}
#Entity
class Address {
#Id
Long id;
#OneToMany(mappedBy = "address")
Set<Address> persons;
}
#Entity
class LinkPersonAddress {
#Id
Long id;
#ManyToOne
#ShallowReference
Person person;
#ManyToOne
#ShallowReference
Address address;
String linkType;
}
My use case is following. I get a specific Person by Id #1, and then mutate the type of specific Address (ie. HOME --> WORK). I save the Person back with the modified Set and let JPA Cascade my changes. Although all Spring Data Repositories for Person, Address, and LinkPersonAddress are annotated with #JaversSpringDataAuditable, I cannot retrieve this "update" using Javers QueryBuilder with the class Person and Id #1. It makes sense as I should query the class LinkPersonAddress instead, but how can I specify that I want only the changes from LinkPersonAddress relevant to Person with Id #1.
PS: Please apologize any typos in code snippets, as I didn't write it in my Dev Environment.
Let's start from the mapping. You did it wrong, Address is a classical ValueObject (see https://javers.org/documentation/domain-configuration/#value-object) not Entity. Because:
Address doesn't have its own identity (primary key genereted by a db sequence doesn't count)
Address is owned by the Person Entity. Person with its Addresses forms the Aggregate.
When you correct the mapping, you can use ChildValueObjects filter, see https://javers.org/documentation/jql-examples/#child-value-objects-filter

JPA recursive entity StackOverflowError

I have a User entity generated in Netbeans from an existing database table. The table has a column lastUpdatedByUser that is a User entity. Most of the tables in this database have a lastUpdatedByUser column and queries against those entities correctly return a user object as part of the result.
Ex. Retrieve FROM ProductionTable WHERE date = 'someDate' has a lastUpdatedByUser object that shows who last updated the table row and the rest of their user attributes.
If the productionTable data is edited in the web-app and submitted I need to update the lastUpdatedByUser column.
Users userUpdating = usersService.selectUserEntityByUserId(userId);
Users userEntity = usersFacade.findSingleWithNamedQuery("Users.findByUserId", parameters);
SELECT u FROM Users u WHERE u.userId = :userId
returns a User object that contains a lastUpdatedByUser that is a User object that contains a lastUpdatedByUser that is a User object that contains a lastUpdatedByUser object.... (I have no clue how many there are, and twenty rows of these adds up)
After I persist this
productionEntity.setLastUpdatedByUser(userUpdating);
I get Json StackOverflowError in the next request for the updated entity
gson.toJson(updatedProductionEntity)
The Users entity definition:
#OneToMany(mappedBy = "lastUpdatedByUser")
private Collection<Users> usersCollection;
#JoinColumn(name = "LastUpdatedByUser", referencedColumnName = "UserId")
#ManyToOne
private Users lastUpdatedByUser;
#OneToMany(mappedBy = "lastUpdatedByUser")
private Collection<Production> productionCollection;
How can edit that such that I continue to get a user object as part of other entities like Production, but only a single lastUpdatedByUser object for a User entity?
Thanks for any insight.
I'm guessing this is my issue:
#JoinColumn(name = "LastUpdatedByUser", referencedColumnName = "UserId")
as I found a FK in the Users table to its own UserId
Love refactoring
================================
Drop that FK from the Users table and regenerate the entity in Netbeans and I get
private Integer lastUpdatedByUser;
like it should be
instead of
private Users lastUpdatedByUser;
Now I get to edit all the entities that have valid FKs into the Users table and code and...
Thanks for listening.

How do I properly annotate two JPA entities which are in a parent child relationship?

Maybe this is a question with an easy answer ... but I don't get it running. At persist() I get the exception that the referential key in the child table is null (which of course is not allowed by the database). I have a recipe and some steps for preparation.
I'm using EclipseLink 2.4.1
Recipe.java (rcpid is autoset by JPA)
#Entity
public class Recipe {
#Id
long rcpid;
List<Recipestep> recipesteps = new ArrayList<>();
#OneToMany(
cascade=CascadeType.ALL,
fetch=FetchType.EAGER,
mappedBy="recipe",
targetEntity=Recipestep.class )
// This does NOT work. Following line tries to access a join-table !!!
// #JoinColumn(name="rcpid", referencedColumnName="rcpid")
public List<Recipestep> getRecipesteps() { return recipesteps; }
// some more attributes, getters and setters
}
Recipestep.java (rpsid is autoset by JPA)
#Entity
public class Recipestep {
#Id
long rpsid;
Recipe recipe;
#ManyToOne( targetEntity=Recipe.class )
#JoinColumn( name="rcpid" )
public Recipe getRecipe() { return recipe; }
// some more attributes, getters and setters
}
The code above is a valid workaround. However to have clean (and supportable) code, the relationship should be only one-way with a collection in the parent which references all its children.
You have mapped this as a unidirectional one to many, but have two mappings for the recipestep rcpid database column. Try changing the long rcpid to
#ManyTOne
Recipe rcp;
And then remove the joincolumn definition from the oneToMany and make it bidirectional by marking it as mappedby the rcp manyToOne relation. An example is posted here http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Relationship_Mappings/Collection_Mappings/OneToMany
Eclipselink will always insert nulls on unidirectional oneToMany relations using a joincolumn when first inserting the target entity, and then update it later when it processes the Recipe entity. Your rcpid mapping in Recipestep is also likely null, which means you have two write able mappings for the same field which is bad especially when they conflict like this.
You are experiencing the default JPA behaviour. Adding an entity to the recipesteps list is not sufficient to create a bidirectional relation.
To solve the issue you need to set the rcpid explicitly on every element in the list.
EDIT: I think the issue is that JPA does not know where to store the id of the Recipe in the Recipestep table. It assumes a name ("recipebo_rcpid"), but your table seems to lack it.
Try adding the column "recipe_id" to the Recipestep table and a mappedBy attribute to the #OneToMany annotation:
#OneToMany(
cascade=CascadeType.ALL,
fetch = FetchType.EAGER,
mappedBy = "recipe" )
You probably do not need the targetEntity attribute in the annotation- the List is typed already.

Advanced JPA Mapping with Compound keys - OneToMany relationship

I am using JPA 1.0 and have following tables, namely, Type, Guide and Address (names simplified for clarity and highlighted in bold) It is a scenario, where in relationships between 3 tables is built on compound keys. Non key fields for every table are below the solid line.
Relationships
Type One --------> Many Guide
Guide Many <---------- One Address
Type
Code PK
Date1 PK
Name
Guide
Code FK
Date1 FK
Addr Identifier FK
Date2 FK
Value
Address
Addr Identifier PK
Date2 PK
Postal Code
(Pardon the formatting issue above)
I would like to start with Type table and unsing the compound key Code and Date1, get multiple rows (as a list) from Guide table. Then using Addr Identifier and Date2 from the row I want to get a single row in Address table. Please note these are reference tables and the data does not change, so there are no deletes or updates on any of these tables
I have tried this simple set of annotations that are returning empty list. (code is implified for clarity)
1)
#Entity
#Table(name = "Type")
public Class Type
#OneToMany(mappedBy = "type", fetch = FetchType.EAGER)
private List<Guide> listGuide;
getListGuide() {
return listGuide;
}
2)
#Entity
#Table(name = "Guide")
public Class Guide
#ManyToOne
#JoinColumns({#JoinColumn(name = "Code"),
#JoinColumn(name = "Date1") })
private Type type;
When I use getListGuide() I am getting an empty list.
Can you please suggest a solution?
I also need a mapping solution between Guide and Address entities.
Regards,