NHibernate Set Property Default Value - nhibernate

Is it possible to set the default value of a property in NHibernate? Here is the scenario:
I have a self join table Category. The class and table structure are as follows:
Category
int Id
string Name
Category ParentCategory
Category
int Id not null
varchar Name not null
int ParentCategoryId not null
If a category has no parent, the ParentCategoryId must be 0.
How do I do this? TIA.

If nHibernate is enforcing this relationship I don't believe you can make it form an invalid relationship. I'd create a dummy parent record 0 in the database and just assign everything to that.

If the ParentCategoryId is not constrained by a foreign key, then you can have in your code ... something like :
class Category{
....
public static Category NoParent{
get{ return new Category{Id = 0}; }
}
....
}
and now, instead of setting to null, just set it to NoParent. Or in the setter of ParentCategory, if value is null, then set it to NoParent.
This is basically Spencer Ruport's ideea :P

Related

Laravel Query Builder pivot table connection

I'm trying to get the all related countries which the country is belongs to the regions it is many to many relation.
I want it in the query builder realations
this I pivot table
id bigint unsigned auto_increment
primary key,
country_id bigint unsigned not null,
region_id bigint unsigned not null
Region Model
public function r_countries()
{
return $this->belongsToMany(Country::class, "country_regions","region_id","country_id");
}
Country Model
public function r_regions(): BelongsToMany
{
return $this->belongsToMany(Region::class, "country_regions", "country_id", "region_id");
}
I tied this it works
$region = \App\Models\Country\Region::findOrFail(23);
$region->r_countries()->pluck("countries.title");
You can use
Model::whereHas('relation_name', function($query) use($varname){
$query->where(condition);
})->get()

How to update the nested tables in sql using gorm?

Here the code is written in Go. I am using two tables where one table has a foreign key that refers to the other table's primary key. Let's say I have a database as following struct defined:
type User struct{
ID uint `gorm:"primary_key;column:id"`
Name string `gorm:"column:name"`
Place place
PlaceID
}
type Place struct{
ID uint `gorm:"primary_key;column:id"`
Name string `gorm:"column:name"`
Pincode uint `gorm:"column:pincode"`
}
And the sql schema is:
create table place(
id int(20) NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
pincode uint(20) NOT NULL,
PRIMARY KEY (id),
)
create table user(
id int(20) NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
place_id uint(20) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (place_id) REFERENCES place(id)
)
Now while inserting in user by gorm as:
place := Place{Name:"new delhi",Pincode:1234}
user := User{Name: "sam", Age: 15, Place: place}
err = db.Debug().Create(&user).Error
//It inserts to both user and place table in mysql
//now while updating to name in user table as Samuel and place as
//following
place := Place{Name:"mumbai",Pincode:1234}
err = db.Debug().Model(&User{}).Where("id =?",
1,).Update(&user{Name:"Samuel",Place:place}).Error
It updates the row in user table but creates a new row in place table.But it should update the matching row in place table and not create a new one
Is there any way to do it? Here I am not using auto migrate function to create db tables.
The answer to your question should be sought in a relations or Association Mode.
The example below shows how to add new associations for many to many, has many, replace current associations for has one, belongs to
db.Model(&user).Association("Place").Append(Place{Name:"mumbai",Pincode:1234})
Or you can replace current associations with new ones:
db.Model(&user).Association("Place").Replace(Place{Name:"mumbai",Pincode:1234},Place{Name:"new delhi",Pincode:1234})
Probably It's creating a new row because you didn't set the ID on Place{Name:"mumbai",Pincode:1234}.

OpenJPA: Assign a sequence generated value to ID if null

I am using jpa for persisting my database along with java pojos
#Entity
#Table(schema = "CENTRALSERVICES", name = "APPLICATION")
public class Application {
#Id
#Column(name = "id", nullable = false, length = 128)
private long id;
}
My database is like this:
CREATE TABLE CENTRALSERVICES.APPLICATION(
id bigint(8) NOT NULL, PRIMARY KEY(id));
The problem is that each application object that I persist was having an Id till now, but the requirement changed and now its not guaranteed if Id will be there. I saw something with sequence but I want to assign a sequence generated value only when the Id is null.
How to solve this. Please help
I changed my database schema and now my primary key is autogenerated whereas id for my application object I have created another field which can be null.

NHibernate Mapping a Table Were the Primary Key is Also a Foreign Key

I have 2 tables as follows:
create table Users
(
UserId int primary key identity not null
)
create table UserExternalKeys
(
UserIdRef int primary key not null,
ExternalKey varchar(50) unique not null
)
alter table UserExternalKeys
add constraint fk_UsersExternalKeys_Users
foreign key (UserIdRef)
references Users (UserId)
Each user can have a 0 or 1 external keys. Things are setup this way because adding a nullable unique column to SQL Server does not allow for more than 1 null value.
Based on Ayende's post, it seems like this could be handled using a <one-to-one> mapping. However, this would require the UserExternalKeys table to have its own primary key.
The new schema would look something like this:
create table Users
(
UserId int primary key identity not null,
ExternalKeyRef int null
)
create table UserExternalKeys
(
UserExternalKeyId int primary key identity not null,
ExternalKey varchar(50) unique not null
)
alter table Users
add constraint fk_Users_UsersExternalKeys
foreign key (ExternalKeyRef)
references UserExternalKeys (UserExternalKeyId)
I think this would work, but it feels like I would only be adding the UserExternalKeyId column to appease NHibernate.
Any suggestions?
If a user can have 0 or 1 external keys why not design the tables as:
create table Users
(
UserId int primary key identity not null
ExternalKey varchar(50) null
)
and use one of the known workarounds for this problem. If you're using SQL Server 2008 you can use a filtered index. If you're using an earlier version you can use a trigger, an indexed view (2005), or the nullbuster workaround.
You could also keep your original schema and map the relationship as one-to-many from Users to UserExternalKeys. Map the collection as a private member and expose access to it through a property:
private IList<UserExternalKeys> _externalKeys;
public string ExternalKeys
{
get
{
if (_externalKeys.Count() == 1)
{
return _externalKeys.ElementAt(0).ExternalKey;
}
else
{
// return null or empty string if count = 0, throw exception if > 1
}
}
set
{
if (_externalKeys.Count() == 0) { // add key and set value }
else { // set value if count = 1, throw exception if > 1 }
}
}

I want generate INSERT which include my Primary Key (not generated) by NHibernate. How to map Id column for this?

I have table CUSTOMER where CUSTOMER_ID is primary key.
Table
CREATE TABLE [CUSTOMER](
[CUSTOMER_ID] [int] NOT NULL,
[START_DATE] [varchar(30)] NOT NULL,
CONSTRAINT [PK_CUSTOMER] PRIMARY KEY CLUSTERED ( [CUSTOMER_ID] ASC .....
Mapping
public class CustomerMap : ClassMap<Customer> {
public CustomerMap()
{
WithTable("CUSTOMER");
Id(x => x.CustomerID, "CUSTOMER_ID");
Map(x => x.Name, "NAME");
}
}
I need to handle assigning of the CustomerID property manually. For example I created new Customer with CustomerID = 777 and name "stackoverflow".
When I call method Session.SaveOrUpdate(customer);
I want NHibernate to generate me SQL like this:
INSERT INTO [CUSTOMER] ([CUSTOMER_ID] ,[NAME]) VALUES (777,'stackoverflow')
Unfortunately I'm getting errors.
Main issue here is that Nhibernate tries to generate ID for me. But I want to save my entity exactly with 777.
I think there should be way to setup mapping for Id() some another way so this will allow me do what I want.
Please help.
Depending on how you do your NHibernate mappints (fluent or hbm) you can setup your ID property to manually assign the id. I believe the default is to let the server assign the id.