How to Implement Many To Many for Spring and Hibernate? - java

I would like to implement this relationship in Java Spring and Hibernate:
In my GnrlOrgChargeCode class, I have:
#OneToMany (targetEntity=IOrgChargeCodeCond.class, mappedBy="gnrlOrgChargeCode", fetch=FetchType.EAGER)
private List <IOrgChargeCodeCond> orgChargeCodeConds;
and in my OrgChargeCodeCond class, I have:
#ManyToOne
private IGnrlOrgChargeCode gnrlOrgChargeCode;
#OneToMany
private List <IBillingCondition> billingCondition;
and in my BillingCondition class:
#OneToMany
private List <OrgChargeCodeCond> orgChargeCodeCond;
and in my OrgChargeCodeRule class:
#ManyToOne
private BillingRule billingRule;
and in my BillingRule class:
#OneToMany(mappedBy = "billingRule")
private List<OrgChargeCodeRule> orgChargeCodeRules;
But when I startup Tomcat, I get this error:
Could not determine type for: java.util.Set, at table: ORG_CHARGE_CODE_COND, for columns: [org.hibernate.mapping.Column(billingCondition)]
My query is this:
select from GnrlOrgChargeCode gocc
join OrgChargeCodeRule occr
join BillingRule br
join OrgChargeCodeCond occc
join BillingCondition bc
where gocc.orgId = ?
assuming gocc.orgId is valid and there are rows in gocc.
Please help. thanks.

I think here is the problem:
OrgChargeCodeCond:
#OneToMany
private List <IBillingCondition> billingCondition;
BillingCondition:
#OneToMany
private List <OrgChargeCodeCond> orgChargeCodeCond;
So you are actually defining a #OneToMany relation in both directions. From your diagram the BillingCondition should have #ManyToOne.
If you need a many-to-many relationship, you can try to make this work with #ManyToMany annotations on both sides. But I wouldn't recommend it, better add another entity and create #OneToMany in between.
Another "pro tipp", have a look at https://bootify.io, you can create or import your schema and get out your Hibernate entities.

Related

JPA: How do I set up an entity with several children and several parents of same entity type?

I'm trying to model a business entity, where said business can have several parent businesses and several child businesses. I'm not sure which relationships are suited, or even what mapping is appropriate. I'm familiar with SQL but new to ORM in Java.
My thinking is that a business can have many or none children, and a business can have many or none parents. Therefore I've tried setting both as OneToMany but also as OneToMany, both resulting in this error: Illegal use of mappedBy on both sides of the relationship.
The implementation:
#Entity
public class Business{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "parentOrgs")
private Collection<Business> chlidOrgs;
#OneToMany(mappedBy = "chlidOrgs")
private Collection<Business> parentOrgs;
// --- Getters and setters below ---
What am I not understanding here? Any and all help much appreciated.
Your current mapping is syntactically incorrect, because only one side of the relationship can be owning side. Owning side is the field defined by value of mappedBy attribute. More detailed explanation can be found from here.
Also removing mappedBy from the one side does not solve the problem, because counterpart of OneToMany must be ManyToOne. Removing it from the both sides leaves us with two unirectional associations, which is also not what is needed.
Because each Business can have multiple parents and it seems to be preferred to be able to navigate directly to the childrens as well, solution is to use bidirectional ManyToMany:
#Entity
public class Business {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToMany(mappedBy = "parents")
private Collection<Business> childrens;
#ManyToMany
private Collection<Business> parents;
}
From database point of view this means following tables:
Business(id)
Business_Business(childrens_id, parents_id)
When necessary, name of the join table and columns can be controlled via JoinTable.

How to add list of Strings to entity - Spring, Hibernate

I have Spring Boot project with DB. I've already get table, let's call it "People". I need to add a second table "People_Strings" with two columns: People_id and String. I need to include many strings for every row from People.
How can I map it in my People entity in project?
Edit: I need to do this without creating separete class for String or for People_Strings
If you only need that, you can add the following property to the People entity class:
#ElementCollection
public List<String> strings;
What you need is #OneToMany relation between people and strings. Something like the following will work for you.
#Entity
#Table(name = "People")
public class People{
#Id
#GeneratedValue
private Long id;
#OneToMany(fetch= FetchType.EAGER, cascade=CascadeType.ALL, mappedBy = "peopleId")
private List<PeopleStrings> PeopleStrings;
#Entity
#Table(name = "People_Strings")
public class PeopleStrings{
#Id
#GeneratedValue
private Long peopleId;
#ManyToOne
#JoinColumn(name="peopleId")
private String string;
You'll want a #OneToMany relationship on the Person object (please don't use plurals, eg People). And possibly a #ManyToOne relationship on the PersonString object (again no plurals)
https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/OneToMany.html
https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/ManyToOne.html
This is kinda basic question and I suggest you to read Hibernate "Get Started" first. (one-to-many / many-to-one relations especially)

JPA Hibernate unexpectedly fetches records of #OneToOne mapped entity, should I change mapping to #ManyToOne or do something else?

I have an entity with #OneToOne mapped subentity:
#Entity #Table
public class BaseEntity {
#Id
private String key;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private InnerEntity inner;
}
#Entity #Table
public class InnerEntity {
private String data;
}
It was working perfectly on persist and merge operations until I decided to fetch all records in a named query (SELECT e FROM BaseEntity e). Problems are that after calling it, Hibernate fetches all records from BaseEntity and then executes distinct queries for each InnerEntity. Because table is quite big it takes much time and takes much memory.
First, I started to investigate if getInner() is called anywhere in running code. Then I tried to change fetchType to EAGER to check if Hibernate it's going to fetch it all with one query. It didn't. Another try was to change mapping to #ManyToOne. Doing this I've added updatable/insertable=false to #JoinColumn annotation. Fetching started to work perfectly - one SELECT without any JOIN (I changed EAGER back to LAZY), but problems with updating begun. Hibernate expects InnerEntity to be persisted first, but there's no property with primary key. Of course I can do this and explicity persist InnerEntity calling setKey() first, but I would rather solve this without this.
Any ideas?
If you want inner field to be loaded on demand and your relation is #OnToOneyou can try this
#OneToOne(fetch = FetchType.LAZY, optional = false)
When using HQL hibernate doesn't consider the annotations, so you should tell it how to work.
In your case you should right the HQL like this:
SELECT e FROM BaseEntity as e left join fetch e.inner

Storing data using hibernate for inter related tables

I have two tables (say table A and table B). Table B has foreign key from table A primary key. I generated my java entities using netbeans IDE and i now have something like:
For table A:
#Entity
#Table(name = "WORKFLOW_TRANSACTION")
public class WorkflowTransaction implements {
#OneToMany(mappedBy = "wtId")
private Collection<WorkflowTask> workflowTaskCollection;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "APP_ID")
private BigDecimal appId;
.
.
.
For table B:
#Entity
#Table(name = "WORKFLOW_TASK")
public class WorkflowTask implements Serializable {
#JoinColumn(name = "WT_ID", referencedColumnName = "APP_ID")
#ManyToOne
private WorkflowTransaction wtId;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "TASK_ID")
private BigDecimal taskId;
#Column(name = "STEP_NUM")
private BigInteger stepNum;
.
.
.
Now my questions are:
What is the correct way to save data, should I create object for table B entity and set it in table A entity and then save table A?
I am generating entity beans using netbeans IDE feature. Are there any known disadvantages of it?, if yes, what?
You have bi-directional association, so you need to setTable B property in Table A entity class and also vice-versa. Since you have not declared cascading, you need to save the Table A entity first and then Table B entity.
Alternatively, if you save Table B and then Table A entity classes, the hibernate generates an extra SQL update command to maintain the relationship.
But if you want hibernate to save Table B entity when you save Table A entity then you need to add Cascade property:
#OneToMany(mappedBy = "wtId", cascade=CascadeType.ALL)
I don't think you will have any disadvantages if you use Netbeans for generating the entity classes, it save you time in writing the entities. But if you want to learn then writing entities without Netbeans is good.
To achieve this you can use two type of techniques XML mapping or Annotations
In both these techniques the common point is use
cascade="save-update"
What happens is that you set an attribute in one table getter and it will automatically insert into the many relation when inserting into one relation table

How can I map double relationships JPA?

I need map at JPA something like this:
How I can map two relationships between two "tables", one of them is primary key and one to one (newClient in advance) and in the other side, a one to many that aint PK?
I tried something like this but it fails.
public class Recommendation implements Serializable {
#Id #OneToOne
#Column(name="...")
private Client newClient;
#ManyToOne
#Column(name="...")
private Client oldFella;
#Column(name="...")
private Boolean wasUsedToGenerateBond;
...
}
Thanks!
it is possible to have multiple ManyToMany relationships between two entities. Each relationship would have its own join table. The default name of the join table may be the same, so you would need to specify the #JoinTable's name.
possible answer here
JPA Problems mapping relationships
more information
Hibernate 4.2, bidirectional #OneToOne and #Id
Like this:
#Id #OneToOne
#JoinColumn(name="id_client1")
private Client newClient;
#ManyToOne
#JoinColumn(name="id_client2")
private Client oldFella;

Categories

Resources