#Id for oracle.rowid - orm

Howto declare #Entity class for oracle table w/o PK?
I has received the error message:
Column "rowid" cannot be resolved on table "LOG"
when doing mapping like this:
#Entity
public class Log implements Serializable {
...
#Id
private ROWID rowid;
...
}

Howto declare #Entity class for oracle table w/o PK?
Mapping a ROWID as Id isn't supported by standard JPA and I couldn't find any obvious proof that EclipseLink is providing an extension for this (I only found this message).
But this is not your only option and the JPA wikibook has a good paragraph about this situation:
No Primary Key
Sometimes your object or table has no
primary key. The best solution in this
case is normally to add a generated id
to the object and table. If you do not
have this option, sometimes there is a
column or set of columns in the table
that make up a unique value. You can
use this unique set of columns as your
id in JPA. The JPA Id does not
always have to match the database
table primary key constraint, nor is a
primary key or a unique constraint
required.
If your table truly has no unique
columns, then use all of the columns
as the id. Typically when this occurs
the data is read-only, so even if the
table allows duplicate rows with the
same values, the objects will be the
same anyway, so it does not matter
that JPA thinks they are the same
object. The issue with allowing
updates and deletes is that there is
no way to uniquely identify the
object's row, so all of the matching
rows will be updated or deleted.
If your object does not have an id,
but its' table does, this is fine.
Make the object and Embeddable
object, embeddable objects do not have
ids. You will need a Entity that
contains this Embeddable to persist
and query it.

Related

Questionable SQL Relationship

I am going through a pluralsight course that is currently going through building an MVC application using an entity framework code-first approach. I was confused about the Database schema used for the project.
As you can see, the relationship between Securities and it's relating tables seems to be one-to-one, but the confusion comes when I realize there is no foreign key to relate the two sub-tables and they they appear to share the same primary key column.
The video before made the Securities model class abstract in order for the "Stock" and "MutualFund" model classes to inherit from it and contain all relating data. To me however, it seems that same thing could be done using a couple of foreign keys.
I guess my question is does this method of linking tables serve any useful purpose in SQL or EF? It seems to me in order to create a new record for one table, all tables would need a new record which is where I really get confused.
In ORM and EF terminology, this setup is referred to as the "Table per Type" inheritance paradigm, where there is a table per subclass, a base class table, and the primary key is shared between the subclasses and the base class.
e.g. In this case, Securities_Stock and Securities_MutualFund are two subclasses of the Securities base class / table (possibly abstract).
The relationship will be 0..1 (subclass) to 1 (base class) - i.e. only one of the records in Securities_MutualFund or Securities_Stock will exist for each base table Securities row.
There's also often a discriminator column on the base table to indicate which subclass table to join to, but that doesn't seem to be the case here.
It is also common to enforce referential integrity between the subclasses to the base table with a foreign key.
To answer your question, the reason why there's no FK between the two subclass instance tables is because each instance (with a unique Id) will only ever be in ONE of the sub class tables - it is NOT possible for the same Security to be both a mutual fund and a share.
You are right, in order for a new concrete Security record to be added, a row is needed in both the base Securities Table (must be inserted first, as their are FK's from the subclass tables to the base table), and then a row is inserted into one of the subclass tables, with the rest of the 'specific' data.
If a Foreign Key was added between Stock and Mutual Fund, it would be impossible to insert new rows into the tables.
The full pattern often looks like this:
CREATE TABLE BaseTable
(
Id INT PRIMARY KEY, -- Can also be Identity
... Common columns here
Discriminator, -- Type usually has a small range, so `INT` or `CHAR` are common
);
CREATE TABLE SubClassTable
(
Id INT PRIMARY KEY, -- Not identity, must be manually inserted
-- Specialized SubClass columns here
FOREIGN KEY (Id) REFERENCES BaseTable(Id)
);

exclusive/disjoint inheritance in SQLite

I was wondering how to implement exclusive inheritance in SQlite. By doing simply
create table Class (id integer primary key);
create table Sub1(id integer primary key references Class(id));
create table Sub2(id integer primary key references Class(id));
I have simple inheritance which does not prevent a Class to be both Sub1 and Sub2. I am looking for a way to enforce that a Class cannot be both (and optionnally, enforce it to be at least one of them).
In theory this could be possible with checks, e.g. for Sub2, something like
create table Sub2(id integer primary key references Class(id)
check(not exists(select 1 from Sub1 where Sub1.id = id limit 1)));
but this has the drawback that it would require maintenance as subclasses are added, and also that it is not accepted by SQLite (subqueries prohibited in CHECK constraints). This does not work when the check is at the table level either.
EDIT
Found a similar question (and related answers) on SO here.
You could try to use triggers (http://www.sqlite.org/lang_createtrigger.html).
For instance, you could implement your needs by creating a trigger for the table Sub(n) that, when a record is inserted in Sub(n), checks that its primary key is not alread present in Class; if it is present than fails since this means that another record with the same primary key is already present in another Sub(k) table, otherwise it insert the (primary key of the) record in Class.
In this way, you can add tables corresponding to subclasses without modifying the code of the previous tables.

Can I map a field #Id when it is not the id in the database?

I have a database table that has three fields: two of them are a composite key for the table, and the other one is an autogenerated field that is not the id of the table. When mapping this table to a JPA entity, can I map the autogenerated field as the #Id, even when it is not? If yes, what are the implications? Note: I cannot change the database.
Yes, you can. This is actually often the case when a Hibernate entity is mapped to a database view which is defined on top of multiple real tables (and other views).
If you don't intend to create new instances of that entity through Hibernate, then there are no implications (if the key is really unique of course).
If you will be persisting new instances with Hibernate, then be sure to pick the appropriate identifier generation strategy.
You should not - #Id has special meaning and will be used as the primary key by hibernate.
The #GeneratedValue annotation works only if #Id is also present, so you cannot use that on the non-id field. More details here - there are possible alternatives depending on which db you are using.

Create a new record with an assigned PK - Castle ActiveRecord

I have a table with a GUID primary key. In ActiveRecord it is setup with a PrimaryKeyType.GuidComb. Is it possible to create this record with a manually assigned PK? If I set the primary key in the record and run Create() a new ID is assigned. If I run Save() I get an error (as one would expect).
The why:
This table is in two databases. Records need to be copied between these two databases on occasion. I would like to retain the ID as the record moves across the DBs.
No. A primary key is either generated (e.g. GuidComb) or manually assigned, it can't be both. You could create two classes that inherited from a base class defining all properties except the primary key, then each of these two classes would define their primary key as assigned or generated. But I'd recommend using SQL here, as a single INSERT INTO ... SELECT will be more efficient than using NHibernate/ActiveRecord.
I ended up setting the PrimaryKeyType to Assigned. Then I handled it with an overrided Create function:
public override void Create() {
if (ID == default(Guid)) ID = GUIDGenerator.Generate();
base.Create();
}
It would have been better to put this in OnSave, but the primary key cannot be modified in the interceptor. This works for my application, however this code will only be called if the object is explicitly created. It will not work if the object is created by cascade.

Fluent-NHibernate table mapping with no primary key

I am trying to create a mapping to a database table that has no primary keys/references.
public class TestMap : ClassMap<<Test>Test> {
public TestMap() {
WithTable("TestTable");
Map(x => x.TestColumn);
}
}
This fails and expects id or composite-id. Is this possible in fluent nhibernate?
In Oracle at least, I have used "ROWID" for this. For mssql you might use the "ROW_NUMBER()" builtin function for readonly access to the table, but I haven't tried that...
No. You'll have to add a surrogate primary key, such as an identity column in SQL Server, to map this table. As far as I know, this isn't supported by NHibernate itself.
Why don't you have a primary key on this table?
This functionality isn't supported by nhibernate as far as I know. As a general rule of thumb, however, you should really always have some kind of ID and if you find yourself in a situation where you think you don't need one you should assess your data model. An ID, whether it be a table-specific primary key, or a surrogate key from another table, should exist. This not only ensures that nhibernate can process the table, but helps performance via indexing.
Before you start assuming nhibernate isn't going to fulfill your needs, consider why you don't have a key on the table and what kind of sense it makes not to have one.
If we can bring a column from table having no primary key/identity coulmn, then we can use fluent as below:
Id(x => x.TempID).Column("TempID");
If the table contains data that belongs to another entity, you could map it as a collection of components. Components are not identified by themselves, but they belong to another entity, which is identified.
You can map an entity to a table without keys defined in the database. I do so in legacy SQL Server databases. However, the table must have a candidate key (some set of columns that actually stores a unique combination of values). The concept of entity involves the notion of some kind of identity.
Instead of this, what you're trying in your code is to map an entity without identity, wich isn't possible.