Auto Generated Id Using Fluent NHibernate with Oracle 11g - oracle

I am having issues inserting records using Fluent NHibernate. The code is trying to get a number from a sequence that is non-existent for the KEY field.
{"could not insert: [Class Name ][SQL: INSERT INTO Schema.TableName (KEY, ID) VALUES (hibernate_sequence.nextval, ?) returning KEY into :nhIdOutParam]"}
Of course the hibernate_sequence sequence doesn’t exist in the database. If I do an insert using SQL Developer say:
INSERT INTO Schema.TableName (ID) VALUES (90); this works and my primary key (KEY) is auto-generated.
I know you can use a sequence to auto generate this value using GenerateBY.Sequence() but is there a way to insert the record using the SQL statment about using Fluent Nhibernate?
I have my class mapped to the primary key in my class for ex.
Id(x => x.Id, "KEY");

Use this. It will insert all of the fields except for the Id which will let Oracle set it for you.
Id(x => x.Id, "KEY").GeneratedBy.Increment();

Related

Inserting data from table (SELECT) with REF - Oracle Database

I'm trying to insert all data from Pacient table to Pacient_OR table (Object-Relational). Is there a simple way to do that (one script), if Pacient table has column with Pojistovna_ID (foreign key) and in Pacient_OR table there is REF to the Pojistovna_OR. Both Pojistovna and Pojistovna_OR are populated with the same data, but one is relational, second is based on object type.
I tried this (and more ofc):
INSERT INTO pacient_or
(pacient_or.id,
pacient_or.jmeno,
pacient_or.prijmeni,
pacient_or.datum_narozeni,
pacient_or.rodne_cislo,
pacient_or.telefon,
pacient_or.krevni_skupina,
pacient_or.rodinna_anamneza,
pacient_or.adresa,
pacient_or.pojistovna)
SELECT pacient.id,
pacient.jmeno,
pacient.prijmeni,
pacient.datum_narozeni,
pacient.rodne_cislo,
pacient.telefon,
pacient.krevni_skupina,
pacient.rodinna_anamneza,
Adresa_typ(pacient.ulice, pacient.mesto, pacient.psc),
(SELECT Ref(poj)
FROM pacient pac,
pojistovna_or poj
WHERE pac.pojistovna_id = poj.id)
FROM pacient;
This code throws error:
single-row subquery returns more than one row
Do not use pacient pac in the subquery. Link it to the pacient in your main from-clause. And even better do not use a subquery for this.

Way to get GORM/Hibernate to work with trigger that sets primary key

I have an existing Oracle database that sets the primary key for an insert via a trigger.
TRIGGER SET_schedtemplate_id_template
BEFORE INSERT
ON schedtemplate
FOR EACH ROW
BEGIN
SELECT schedtemplate_id_template_SEQ.NEXTVAL
INTO :NEW.id_template
FROM DUAL;
END;
We have other applications that depend on this approach for this database
I want to be able to map this database in GORM in my domain object
static mapping = {
autoTimestamp true
table 'schedtemplate'
version false
id column: 'id_template', generator: 'sequence', params: [sequence: 'SCHEDTEMPLATE_ID_TEMPLATE_SEQ']
}
The problem with this approach is that GORM increments the sequence to say 12 but then on insert the sequence gets incremented again to 13. This means other objects in the object graph violate foreign key constraints as they are using GORM's 12 instead of the trigger's 13.
It appears the hibernate setting hibernate.jdbc.use_get_generated_keys = true was developed for this purpose.
How do I configure GORM/Grails to use this setting?
The trigger assigned identity column in Hibernate was discussed here hibernate and DB triggers
Now there is a question, how to configure it in GORM.
Try to use the custom identity generator described above like this :
static mapping = {
...
id column: 'id_template', generator: 'jpl.hibernate.util.TriggerAssignedIdentityGenerator'
}

Sequel adding a "returning null" to my inserts. How do I disable it?

I'm using Ruby Sequel (ORM gem) to connect to a Postgres database. I'm not using any models. My insert statements seem to have a "returning null" appended to them automatically (and thusly won't return the newly inserted row id/pk). What's the use of this? And why is this the default? And more importantly, how do I disable it (connection wide)?
Also, I noticed there's a dataset.returning method but it doesn't seem to work!
require 'sequel'
db = Sequel.connect 'postgres://user:secret#localhost/foo'
tbl = "public__bar".to_sym #dynamically generated by the app
dat = {x: 1, y: 2}
id = db[tbl].insert(dat) #generated sql -- INSERT INTO "public"."bar" ("x", "y") VALUES (1, 2) RETURNING NULL
Don't know if it matters but the table in question is inherited (using postgres table inheritance)
ruby 1.9.3p392 (2013-02-22) [i386-mingw32]
sequel (3.44.0)
--Edit 1 -- After a bit of troubleshooting--
Looks like the table inheritance COULD BE the problem here. Sequel seems to run a query automatically to determine the pk of a table (in my case the pk's defined on a table up the chain), not finding which, perhaps the "returning null" is being appended?
SELECT pg_attribute.attname AS pk FROM pg_class, pg_attribute, pg_index, pg_namespace WHERE pg_class.oid = pg_attribute.attrelid AND pg_class.relnamespace = pg_namespace.oid AND
pg_class.oid = pg_index.indrelid AND pg_index.indkey[0] = pg_attribute.attnum AND pg_index.indisprimary = 't' AND pg_class.relname = 'bar'
AND pg_namespace.nspname = 'public'
--Edit 2--
Yup, looks like that's the problem!
If you are using PostgreSQL inheritance please note that the following are not inherited:
Primary Keys
Unique Constraints
Foreign Keys
In general you must declare these on each child table. Do for example:
CREATE TABLE my_parent (
id bigserial primary key,
my_value text not null unique
);
CREATE TABLE my_child() INHERITS (my_parent);
INSERT INTO my_child(id, my_value) values (1, 'test');
INSERT INTO my_child(id, my_value) values (1, 'test'); -- works, no error thrown
What you want instead is to do this:
CREATE TABLE my_parent (
id bigserial primary key,
my_value text not null unique
);
CREATE TABLE my_child(
primary key(id),
unique(my_value)
) INHERITS (my_parent);
INSERT INTO my_child(id, my_value) values (1, 'test');
INSERT INTO my_child(id, my_value) values (1, 'test'); -- unique constraint violation thrown
This sounds to me like you have some urgent DDL issues to fix.
You could retrofit the second's constraints onto the first with:
ALTER TABLE my_child ADD PRIMARY KEY(id);
ALTER TABLE my_child ADD UNIQUE (my_value);

Problems with auto generated SQL Server Compact Keys

I use VS2010 to generate a SQL Server Compact database with two simple tables.
Both have a column TheID (int). On one I set unique to true on the other not.
And I set primary key on this column.
CREATE TABLE [TestTab] (
[TheID] int NOT NULL
, [TheVal] nvarchar(100) NOT NULL
);
GO
ALTER TABLE [TestTab] ADD CONSTRAINT [PK_TestTab] PRIMARY KEY ([TheID]);
GO
For the other (with unique set on the column) I get:
CREATE TABLE [TestTab2] (
[TheID] int NOT NULL
, [TheVal] nvarchar(100) NOT NULL
);
GO
ALTER TABLE [TestTab2] ADD CONSTRAINT [PK_TestTab2] PRIMARY KEY ([TheID]);
GO
CREATE UNIQUE INDEX [UQ__TestTab2__00000000000033E9] ON [TestTab2] ([TheID] ASC);
GO
Next I use the SQL Server Compact Toolbox to create a datacontext.
Selecting data works fine - but when I try to update the code it breaks on dc.SubmitChanges().
Simply my WP7 application ends.
A try / catch doesn't help.
TestTab tT = (from A in dC.TestTabs select A).FirstOrDefault();
if(tT != null) {
tT.TheText += "1";
dC.SubmitChanges();
}
If I drop the unique index, the code works fine.
Any ideas why this happens?
Manfred
It is a LINQ to SQL on Windows Phone bug... Your index is a duplicate (the primary key definition also adds an index) - see my blog post here: http://erikej.blogspot.com/2012/04/windows-phone-local-database-tip.html. To get auto generated values, setting a primary keys is not enough, ypou must define the column as IDENTITY as well.

Get the latest inserted PK after submitting a linq insert stored procedure

I have a stored procedure that updates a table using linq, eg: (this is just example code by way)
using (DataContext db = new DataContext())
{
d.sp_Insert_Client( textboxName.Text, textBoxSurname.Text);
}
What I would like to know is how to retrieve (if possible) newly generated primary key of the above inserted row, as I need this primary key as a foreign key to complete another insert.
You have to modify your stored procedure to return that value from database and then regenerate your Linq mapping to update that change in your ORM files. After that your sp_Insert_Client method will return an integer.
The other way to do that is to add another parameter into the query and mark it as output one.
To get last inserted I'd inside your SP use SCOPE_IDENTITY: http://msdn.microsoft.com/pl-pl/library/ms190315.aspx
I think you need to retrieve value by using the output parameter that you can check over here : Handling stored procedure output parameters A Scott Gu post which explain that easily
Procedure
For you
create procdeudre nameofprocedure
#id int output
as
begin
insert in your table statement
--retrieve identity value
select #id = scope_identity();
end
Code

Resources