Hibernate Mapping: How do I create/design a bidirectional relationship ENTITY? - spring

Problem statement
Assume you have report with an attribute call status
but each status change needs to be recorded and by which user.
So you will most likely end up with
REPORT
REPORT_ID
REPORT_STATUS
STATUS_ID
REPORT_ID
but how should I get the current status without "caculation" (ie get last modified date)
I come up with this solution
REPORT
REPORT_ID
CURRENT_STATUS_ID
REPORT_STATUS
STATUS_ID
REPORT_ID
Assume there are more attributes you need, I suspect this way of creating a table have some issues with hibernate when it try to CREATE REPORT then try to CREATE STATUS.
I just tried to created the hibernate mapping using annotation for this relationship.
Everyone I tried to save.. I get
STATUS_REPORT_PK parent key not found
It means that when is trying to create report status, the report is not created yet.
How do I do a proper mapping that allows me to commit both at the same time

There seems to be a logical inconsistency here
Lets say we need to generate a report. Now the report_id is stored but we need a status ID.
But to get a new status we need to specify a report. Since the report is not created the status can't be created and vice versa.
I'm assuming there are a limited number of status's so lets store them in a table called STATUS
REPORT
REPORT_ID
CURRENT_STATUS_ID
REPORT_STATUS
STATUS_ID
REPORT_ID
STATUS
STATUS_ID
First create a new report and attach an object of status to it.
Then create an object of REPORT_STATUS
Just in case you've set a cascade type remove it. Hibernate gets confused sometimes.
EDIT
You seem to be confused over the tables
The report table will hold the report id, data about the report as well as its current status
The report_status table will hold all the previous status's of the report as well as the current one represented as a composite primary key of status_id and report_id
The status table will hold ALL the possible status's a report can have.
For eg. If the possible status's are "On Hold","In production", "Released", "editing" , these will be stored in the status table.
The other 2 tables will reference this for the status they are referring to.

Related

Oracle Apex 20.1 Automatic DML processing not working to save updates

I have created an apex page with static content.
The details are as below:
Pre-rending-> fetch rows from P_IT_PEOPLE table with primary key person_id defined.
Region-> The columns which are to be used defined along with primary key PERSON_ID which is kept hidden.
other items-> P5_ASSIGNED_DEPT,P5_APPROVER,P5_PERSON_NAME.
Region Buttons-> SAVE/CANCEL
SAVE-> Server side-> Submit-> SQL Update action
Processing:
Create process rows of P_IT_PEOPLE
Automatic Row Fetch Legacy
Table name, primary key defined (PERSON_ID)
Supported operations-> only update selected as i just want this page to update the columns person_name, assigned_dept and approver accordingly.
Whatever fields i enter should get updated in the table.
However in app, after i click save, no updates. It is successful but neither db, nor front end, nowhere updates happen.
What am i doing wrong?
[1]: https://i.stack.imgur.com/7JpNA.png
[2]: https://i.stack.imgur.com/UjbXD.png

session item does not change when using lov in primary key

I am implementing a Interactive grid to perform DML operations on a table.
it has combined primary key of two columns
One primary key column is display only and refer to master table and another primary key column I want to have a LOV to select value. LOV is dynamic lov having a display and return value picked from another table.
Inserts are fine but session state item value is set for one row and all the operations are performed on that same row irrespective of which row is selected.
you can see a sample here
https://apex.oracle.com/pls/apex/f?p=128616:2:1964277347439::NO:::
master table name: sample
detail table name: sample_child
primary key in sample child : ID and Name
pop lov is implemented in NAME
LOV values are picked from table: Sample_uncle
LOV display : ID || '-' || NAME
LOV return : ID
you can try to update blabla column of sample_child table to see the issue.
I am not sure how I can give you access to look at the implementation.
I have already tried all the options I can think of
This is to do with your primary keys, the detail table does not appear to have proper ones, thats why it always tried to update the first entry, and I think this is also why every row is marked when you load the table.
Primary keys also do the annoying thing of refusing to be empty, as you can see if you insert a new row, the middle column(which is a PK) is filled with 't1001'.
Since you are dealing with simple tables(and not a whole bunch of joined tables) I always consider it best to use ROWID as PK. So set ROWID as PK for the master table, and ROWID for the detail table. And have the detail table have a Master table be your master table, and then click on the first column in the detail table and set the master column for it. And I also personaly always hide the column that is linked.
I would advise you use ROWID whenever possible as its just so much easier to work with, it does mean you might need to set up a validation to prevent someone adding duplicated values for your actual PK, but since the PK is in the underlying table, they cant enter it anyways(but if you have a validation, the error will be much prettier), whilst if the column is a PK, APEX will prevent duplicates by default.
I hope this helps

Default value or NULL in Room database entity

I'm trying to understand Room database library. I am struck with a scenario where two tables are linked via #ForeignKey constraint. What I need is, when the parent row is deleted, all the child columns in the child table should be set to NULL or some default value. But when I tried to use
onDelete=SET_NULL or SET_DEFAULT with #ForeignKey
I get the following error:
android.database.sqlite.SQLiteConstraintException: NOT NULL constraint
failed: Log.tagId
From the error I can see that the child column has been set as NOT NULL during the table definition, can someone say how to change it to be NULLABLE since room creates the tables for us? Also, it is ok if we can set a standard default value on the columns. If so, how to set the default value of columns? I think there should be some way else the constants SET_NULL or SET_DEFAULT has no meaning and purpose.
Thanks in advance!

Creating a record history table - How do I create a record on creation?

For a project, I want to have a "History" table for my records. I have two tables for this (example) system:
RECORDS
ID
NAME
CREATE_DATE
RECORDS_HISTORY
ID
RECORDS_ID
LOG_DATE
LOG_TYPE
MESSAGE
When I insert a record into RECORDS, how can I automatically create an associated entry in RECORDS_HISTORY where RECORDS_ID is equal to the newly inserted ID in RECORDS?
I currently have a sequence on the ID in RECORDS to automatically increment when a new row is inserted, but I am unsure how to prepopulate a record in RECORDS_HISTORY that will look like this for each newly created (not updated) record.
INSERT INTO RECORDS_HISTORY (RECORDS_ID, LOG_DATE, LOG_TYPE, MESSAGE) VALUES (<records.id>, sysdate(), 'CREATED', 'Record created')
How can I create this associated _HISTORY record on creation?
You didn't mention the DB you are working with. I assume its Oracle. The most obvious answer is: Use a "On Insert Trigger". You even can get back the ID (sequence) from the insert statement into table RECORDS. Disadvantages of this solution: Triggers are kinda "hidden" code, can slow down processes on massive inserts and you consume like double diskspace on storing data partially redundant. What if RECORDS got updated or deleted? Can that happen and do you have to take care of that as well? The big question is: What is your goal?
There are proved historisation concepts around. Have a look at this: https://en.wikipedia.org/wiki/Slowly_changing_dimension

How to bind multiple tables to single DM form?

I have a DM Form type page, where I would like to show and update values from different tables. By default when I created page, I have been asked for data source, specified only one of the tables, which in fact created process in After Header of type Automated Row Fetch. Also in After Submit a process of type Automatic Row Processing (DML) is created. When I add an item in the page from different table, obviously I am getting an error that the column not found in that table. How can I add more tables into that page, so they will be fetched and updated properly?
There is a common column in all tables, to identify which record I would like to show from each table.
I would like to show and update values from different tables
[...]
There is a common column in all tables, to identify which record I would like to show from each table.
Maybe are you looking for a simple JOIN on your various tables?
Based on Oracle's HR example schema, if you need to display both departments and employees names, you write something like that as your report query:
SELECT department_name as dep_name,
first_name || ' ' || last_name as emp_name
FROM HR.DEPARTMENTS JOIN HR.EMPLOYEES
USING(DEPARTMENT_ID)
In order for this to be usable from APEX form builder, you have to wrap it in a VIEW:
CREATE VIEWS MY_VIEW AS SELECT .... FROM ... JOIN ...
I can't guarantee that the view will be update-able out-of-the-box as Oracle has very specific rules for inherently updatable views -- especially for join views. However, you might be able to make your view updatable anyway by using an INSTEAD OF trigger. If you decide to go that way, maybe worth considering asking an other question on that specific topic if needed.

Resources