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.
Related
I have table user_profile, with 3 fields:
id: UUID, primary key, not null, auto generated
created: TIMESTAMP, not null, auto generated
name: VARCHAR
Below is my code to insert a new row to the table.
// dsl is DslContext, which is a bean, injected by Spring Boot
dsl.newRecord(Tables.USER_PROFILE).apply {
name = "My Name"
insert()
// UserProfile is an immutable pojo class, generated by jooq.
}.into(UserProfile::class.java)
In the code above, "id" field (primary key) is updated to the pojo,
while "created" field (normal field) is "null".
What is the "best way" to include the returning value for "created" field?
There are 2 flags governing this behaviour:
Settings.returnIdentityOnUpdatableRecord, default true
Settings.returnAllOnUpdatableRecord, default false
You want to set the second flag to true as well.
I'm trying out pre-defining my database structure using SQL schema and then utilising it within my Kotlin code. I'm using Spring Boot and Spring Data JDBC.
Here's what I currently have so far:
My User class:
data class User(
#Column(name = SqlQueries.Users.Entries.id) // "user_id"
val id: String?,
#Column(name = SqlQueries.Users.Entries.firstName) // "user_first_name"
var firstName: String = "Joe",
#Column(name = SqlQueries.Users.Entries.lastName) // "user_last_name"
var lastName: String = "Bloggs",
#Column(name = SqlQueries.Users.Entries.username) // "user_username"
var username: String = "${firstName}.${lastName}",
#Column(name = SqlQueries.Users.Entries.password) // "user_password"
#JsonIgnore
var password: String = "password1",
#Column(name = SqlQueries.Users.Entries.isActive) // "user_is_active"
val isActive: Boolean = true,
)
My UserRole class:
data class UserRole(
#Column(name = SqlQueries.Lookups.UserRoles.Entries.id)
val id: Int? = null,
#Column(name = SqlQueries.Lookups.UserRoles.Entries.roleName)
val name: String = "",
)
My Schema:
-- ===================================================================================
-- Lookup Tables
-- ===================================================================================
-- Creates our User Table if one does not exist within the database already.
CREATE TABLE IF NOT EXISTS table_users(
user_id VARCHAR(60) DEFAULT RANDOM_UUID() UNIQUE PRIMARY KEY,
user_first_name VARCHAR NOT NULL,
user_last_name VARCHAR NOT NULL,
user_username VARCHAR NOT NULL UNIQUE,
user_password VARCHAR NOT NULL,
user_is_active VARCHAR NOT NULL
);
-- ===================================================================================
-- Lookup Tables
-- ===================================================================================
-- Creates our Roles Lookup Table if one does not already exist within the database.
CREATE TABLE IF NOT EXISTS lookup_roles(
role_id SMALLINT AUTO_INCREMENT UNIQUE PRIMARY KEY,
role_name VARCHAR NOT NULL UNIQUE
);
-- ===================================================================================
-- Junction Tables
-- ===================================================================================
-- Creates our User/Role Junction table if one does not already exist within the database.
-- This will be the foundation of a many to many relationship between the two entities.
CREATE TABLE IF NOT EXISTS junction_user_role(
user_id VARCHAR(60),
role_id SMALLINT,
CONSTRAINT pk_user_role PRIMARY KEY (user_id, role_id),
CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES table_users (user_id),
CONSTRAINT fk_role FOREIGN KEY (role_id) REFERENCES lookup_roles (role_id)
);
As you can see, I've created a User, Role and User/Role table. This is designed to have a many to many relationship.
I'm in the dark with being able to "access" the relationship as a variable which I can use later on.
In my previous "prototype" which had a different design concept I used the following format:
User class:
...
#ManyToMany(fetch = FetchType.EAGER)
#Column(name = "user_roles")
var userRoles: MutableSet<Role> = mutableSetOf(),
...
How would I define and implement this with the new way of doing it?
I don't really speak Kotlin, but I try anyway. Please use ChatGPT or personal experience to fix Kotlin errors ;-)
The first step is to identify the aggregates an what belongs to which aggregate.
I'd suggest that you have a UserRole and a User aggregate, with the later owning the relationship.
This implies that you need to add the relationship to the User, which is your aggregate root for the User aggregate.
Since Role is a different aggregate you'd reference it by id, and you need a separate entity to hold that id
data class User (
...
#MappedCollection(idColumn="user_id")
val roles: Set<RoleRef>
)
data class RoleRef(
val roleId: AggregateReference<Role, Int>
)
If you want to navigate from UserRole to all the User entities having that role, you'd create a repository method in the UserRepository for this.
How this works is detailed in https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates
Also related: Spring Data JDBC many to many relationship management
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}.
I'm using ormlite for Android and I'm trying to get a multiple column unique-constraint. As of now i'm only able to get a unique constraint on indiviudal columns like this:
CREATE TABLE `store_group_item` (`store_group_id` INTEGER NOT NULL UNIQUE ,
`store_item_id` INTEGER NOT NULL UNIQUE ,
`_id` INTEGER PRIMARY KEY AUTOINCREMENT );
and what I want is
CREATE TABLE `store_group_item` (`store_group_id` INTEGER NOT NULL ,
`store_item_id` INTEGER NOT NULL ,
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
UNIQUE( `store_group_id`, `store_item_id` );
In my model I've been using the following annotations for the unique columns:
#DatabaseField( unique = true )
Is there a way to get this to work?
How about using
#DatabaseField (uniqueCombo = true)
String myField;
annotation instead - is it a matter of the uniqueIndexName being faster when accessing items in the table?
Edit:
As #Ready4Android pointed out, we've since added in version 4.20 support for uniqueCombo annotation field. Here are the docs:
http://ormlite.com/docs/unique-combo
There should be no performance differences between using this mechanism versus the uniqueIndexName mentioned below.
Yes. You can't do this with the unique=true tag but you can with a unique index.
#DatabaseField(uniqueIndexName = "unique_store_group_and_item_ids")
int store_group_id;
#DatabaseField(uniqueIndexName = "unique_store_group_and_item_ids")
int store_item_id;
This will create an index to accomplish the unique-ness but I suspect that the unique=true has a hidden index anyway. See the docs:
http://ormlite.com/docs/unique-index
I will look into allowing multiple unique fields. May not be supported by all database types.
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