Spring JPA OneToMany with composite Key mapping - java

I am having issues mapping the following using spring JPA. Let's say I have a order table which has two primary keys. one is a foreign key to customer and another is a foreign key to order Type as seen below:
Customer
+----+------+--+
| id*| name | |
+----+------+--+
| 1 | Joe | |
+----+------+--+
Order
+------------+-------------+
| customerId | orderTypeId |
+------------+-------------+
| 1 | 1 |
+------------+-------------+
OrderType
+----+--------+
| id | type |
+----+--------+
| 1 | online |
+----+--------+
the idea is each customer has a one to many relationship with Orders. the primary key of orders is a combination of the two foreign keys.
any help would be appreciated.

Related

Calling/mapping another entity in getter with hibernate

Consider this simple database schema:
User Relation Property
+-------------+ +--------------+ +---------------+
| -user_id | | -relation_id | | -property_id |
| | | -source_id | | |
| | | -target_id | | |
| | | -type | | |
+-------------+ +--------------+ +---------------+
The relation table contains multiple source and target ids (as STRING) from another tables and "connect" dynamically difficult types of entities. So the source_id can be a user_id and target_id property_id, but also other entities and vice versa.
Now I want in User the properties over the relation table when type is property.
#OneToMany(mappedBy = "source", fetch = FetchType.EAGER)
#Where(clause = "type = 'PROPERTY'")
#ElementCollection
private Set<Relation> properties;
This works perfectly fine. I receive the relation entity with the property id as string in target_id.
Is it possible to resolve this and extend the getter, so that i receive the real property entity?
Like calling the propertyRepository within the user entity. As a newbie in java and jpa/hibernate im a bit lost here.

Define an entity via a custom SQL query in Hibernate 5.1

I'm working with a non normalized 3rd party database meaning I cannot change the schema. I'm trying to map the tables to JPA entities using Hibernate 5.1
There are 2 simple tables A and B:
| A_ID(pk) | | B_ID(pk) |
------------- -------------
| 1 | | 1 |
------------- | 2 |
-------------
Table C has a composite primary key and has a Many-To-One relation to Table A:
| A_ID(pk&fk) | QUANTITY(pk) | VALID_FROM(pk) |
---------------------------------------------------
| 1 | 1 | 2017-05-21 |
| 1 | 1 | 2018-01-01 |
| 1 | 2 | 2017-05-21 |
Table D has a composite primary key:
| A_ID(pk&fk) | QUANTITY(pk) | VALID_FROM(pk) | B_ID(pk&fk) |
--------------------------------------------------------------------
| 1 | 1 | 2018-01-21 | 1 |
| 1 | 2 | 2018-01-21 | 1 |
| 1 | 2 | 2018-05-01 | 2 |
the VALID_FROM column is not part of the join condition between the tables and can take up any value.
I'm trying to set up a relation between Table C and D but because of the VALID_FORM primary key component they cannot be modelled with Many-To-One. And since there is no join table they cannot be modelled with Many-To-Many either.
The best solution would be to create a view like
CREATE VIEW C_NORM AS
SELECT DISTINCT A_ID, QUANTITY
FROM TABLE_C;
which would produce view C_NORM:
| A_ID(pk&fk) | QUANTITY(pk) |
----------------------------------
| 1 | 1 |
| 1 | 2 |
Creating the C_NORM entity on this view could have
a One-To-Many relation with Table C
and another One-To-Many relation with Table D
but I cannot change the schema thus I cannot create a new view.
Is there any way to define an entity as a class with annotations that is basically based on a native SQL query rather than a view or table in the DB?
No that's not possible and it doesn't make sense.
Entities are for update, insert and delete. If you don't want to do any of these operations you shouldn't use entities.
You can use the #SqlResultSetMapping to map a result of a native query to a class
Query q = em.createNativeQuery(
"SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
"FROM Customer c " +
"JOIN Orders o ON o.cid = c.id " +
"GROUP BY c.id, c.name",
"CustomerDetailsResult");
#SqlResultSetMapping(name="CustomerDetailsResult",
classes={
#ConstructorResult(targetClass=com.acme.CustomerDetails.class,
columns={
#ColumnResult(name="id"),
#ColumnResult(name="name"),
#ColumnResult(name="orderCount"),
#ColumnResult(name="avgOrder", type=Double.class)})
})
Or alternatively use QLRM: https://github.com/simasch/qlrm

Join using Criteria API without foreign constraint

I'm really new to the Criteria API and I do not know how I can create a join query for the following situation. I already looked into the Oracle documentation of the Criteria API, but I could not make the examples work.
Say you have the following two tables in your database.
Item Export
---------------------------- ---------------------------
| ItemId | DateUpdated | | ItemId | ExportDate |
---------------------------- ---------------------------
| 1 | 02/02/2016 | | 1 | 02/02/2016 |
---------------------------- ---------------------------
| 2 | 03/02/2016 | | 2 | 03/02/2016 |
---------------------------- ---------------------------
| 3 | 06/02/2016 | | 3 | 05/02/2016 |
---------------------------- ---------------------------
| 4 | 07/02/2016 |
----------------------------
The corresponding entity classes are exact representations of the tables.
The query should join Item with Export, but there is no foreign key from Export.ItemId to Item.ItemId. Further, as a result the query should select Item with ItemId 3, because Export.ExportDate is before Item.DateAdded, and Item with ItemId 4, because the id is not in Export.
How can I do that?

Vaadin: how to set up relation between two SQLContainers?

I have two SQLContainers with the folowing data structure:
SQLContainer SP:
FullUserName | tel | room
SQLContainer MT:
FullUserName | ComputerName | Domain | OS
In my opinion, the foreign key of the both SQLContainers could be: "FullUserName" field?!
How can i set relation (reference) between these containers to get the finally view like this:
FullUserName | tel | room | ComputerName | Domain | OS
?

How to Get DB Field name from ConstraintViolationException - Hibernamte

How to get the Name of the DB field causing ConstraintViolationException while inserting in to Database in hibernate.
I have the Table Like
mysql> desc Mytable;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | bigint(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | UNI | NULL | |
| city | varchar(20) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
And records inthe table are
mysql> select * from Mytable;
+----+--------+-------+
| id | name | city |
+----+--------+-------+
| 1 | SATISH | BLORE |
+----+--------+-------+
1 row in set (0.00 sec)
Now, im trying to insert
"RAMESH","BLORE" through hibernate.
It is throwing ConstraintViolationException due to "BLORE" (CITY) already Exist.
if im trying to insert.
"SATISH","MLORE" through hibernate
It is throwing ConstraintViolationException due to "SATISH" (NAME) already Exist.
My question is
how to get fieldName who is causing the exception ConstraintViolationException through Hibernate.
Since there might be other constraints that could be violated (e.g. combined keys), you only have the name of the constraint that is violated, which in your case might just be the column name (however, I'm not entirely sure about that). You can get the name of the violated constraint by calling getConstraintName() on the ConstraintViolationException.

Categories