Hibernate entity with enum foreign key - oracle

I'm not sure if the topic name makes sense.
Anyway, the problem is that in my table I have column which stores fk to dictionary table and I want to map it in hibernate in a way that getType will return a value from this dictionary. As an example I have row with type id = 1 which in dictionary corresponds to HIGH, and I have such enum declared in java as ProductType, I want to have method
ProductType getType() which will automatically map values from column type to my enum.
If something's not clear, please let me know.
Thanks in advance!

This is the answer to my question
#Column(name="TYPE_ID")
#Enumerated(EnumType.ORDINAL)
private MyType myType;
Of course my enum looks as follows:
public enum MyType {
HIGH(1),
LOW(2);

Related

many to many in gorm v2 error on foreign key

I'm finding it difficult to define many to many relationship using Gorm in following cases
features(feature_id, name, slug)
operations(operation_id, name, slug)
feature_operations(feature_id, operation_id)
type Feature struct {
FeatureID int64 `gorm:"primaryKey;column:feature_id" json:"feature_id"`
Name string `validate:"required" json:"name"`
Slug string `json:"slug"`
Status string `json:"status"`
Operations []Operation `gorm:"many2many:feature_operations;foreignKey:feature_id"`
appModels.BaseModel
}
When using feature_id, I get error
column feature_operations.feature_feature_id does not exist
When using id, I get error
invalid foreign key: id
Looks like you are not using the convention that gorm suggests where you name your primary key columns just id
so in your case your foreignKey should be the name of the field and you also need to use References to specify column that you want to reference. See the example here:
https://gorm.io/docs/many_to_many.html#Override-Foreign-Key
What you need is this:
type Feature struct {
FeatureID int64 `gorm:"primaryKey;column:feature_id"`
Name string
Slug string
Operations []Operation `gorm:"many2many:feature_operations;foreignKey:FeatureID;References:OperationID"`
}
type Operation struct {
OperationID int64 `gorm:"primaryKey;column:operation_id"`
Name string
Slug string
}
After this the join table will be FEATURE_OPERATIONS with two columns FEATURE_FEATURE_ID AND OPERATION_OPERATION_ID
If you dont like the redundant column names then you need to use the two additional attributes joinForeignKey and joinReferences to choose your own names for the columns like so:
gorm:"many2many:feature_operations;foreignKey:FeatureID;joinForeignKey:FeatureID;References:OperationID;joinReferences:OperationID"
All this extra work is needed because your primary keys are FEATURE_ID and OPERATION_ID instead of just ID
If you can rename the column to follow the convention, you will notice life is much easier with gorm

Jooq enum converter uses the ordinal number. How can I switch to use the enum value number instead?

We have an Enum class with customized values. The values are different from their ordinals intentionally for business purpose which I cannot change.
enum class Role(val value: Int) {
EXECUTOR(1),
MONITOR(3),
ADMIN(5),
companion object {
private val map = Role.values().associateBy(Role::value)
fun fromInt(role: Int) = map[role]
}
}
We are using JOOQ and postgres. We use the JOOQ default EnumConverter to convert db role integer values to objects.
ForcedType()
.withUserType("com.company.enums.Role")
.withEnumConverter(true)
.withIncludeExpression("role"),
However we noticed a problem -- the database stored the ordinals of the enum, instead of the values. For example we see in the db in roles column, the db value is 1, and the translated Enum is MONITOR, coz MONITOR has an ordinal of 1.
How can we store the values of Enum into db using JOOQ?
Thank you!
You can of course implement a custom converter from scratch, as you suggested in your own answer. But do note that starting from jOOQ 3.16 and https://github.com/jOOQ/jOOQ/issues/12423, you can simplify that implementation by extending the org.jooq.impl.EnumConverter like this:
class RoleConverter : EnumConverter<Int, Role>(
Int::class.java,
Role::class.java,
Role::value
)
Ohhh I figured it out! There's Custom Converter https://www.jooq.org/doc/latest/manual/code-generation/custom-data-types/ which is exactly what I need.

Is there a way to add a custom column when we create a many2many association in gorm?

I want to know 2 things
I got the following structs from a similar question.
// models/school.go
type School struct {
ID int `gorm:"primary_key"`
Name string `gorm:"not null"`
Accreditations []Accreditation `gorm:"many2many:school_accreditation;"`
}
type Accreditation struct {
// "accreditation" table
ID int `gorm:"primary_key"`
Name string
Description string
}
So, by default this will create a school_accreditation table with 2 columns:
one will have School's ID
other will have Accreditation's ID
My questions:
What is the most efficient way to add another column to the school_accreditation table?
Let's say I want to have the Name field of Accreditation in the school_accreditation table.
2.1) How do I achieve this eg: school_accreditation will have school_id, accreditation_id, accreditation_name
For the 1st question,
It seems the only way of doing it by defining the SchoolAccreditation model & adding fields to it.
Also, it gives me more control over the relationship.
For the 2nd question, I am yet to find a way if there is any!
bost
For the 2nd,
You have to manually get the name from Accreditation & then add it to the column via the defined SchoolAccreditation model.

How do I query an optional column with a secondary index using phantom?

I have a secondary index on an optional column:
class Sessions extends CassandraTable[ConcreteSessions, Session] {
object matchId extends LongColumn(this) with PartitionKey[Long]
object userId extends OptionalLongColumn(this) with Index[Option[Long]]
...
}
However, the indexedToQueryColumn implicit conversion is not available for optional columns, so this does not compile:
def getByUserId(userId: Long): Future[Seq[Session]] = {
select.where(_.userId eqs userId).fetch()
}
Neither does this:
select.where(_.userId eqs Some(userId)).fetch()
Or changing the type of the index:
object userId extends OptionalLongColumn(this) with Index[Long]
Is there a way to perform such a query using phantom?
I know that I could denormalize, but it would involve some very messy housekeeping and triple our (substantial) data size. The query usually returns only a handful of results, so I'd be willing to use a secondary index in this case.
Short answer: You could not use optional fields in order to query things in phantom.
Long detailed answer:
But, if you really want to work with secondary optional columns, you should declare your entity field as Option but your phantom representation should not be an option in order to query.
object userId extends LongColumn(this) with Index[Long]
In the fromRow(r: Row) you can create your object like this:
Sessions(matchId(r), Some(userId(r)))
Then in the service part you could do the following:
.value(_.userId, t.userId.getOrElse(0))
You also have a better way to do that. You could duplicate the table, making a new kind of query like sessions_by_user_id where in this table your user_id would be the primary key and the match_id the clustering key.
Since user_id is optional, you would end with a table that contains only valid user ids, which is easy and fast to lookup.
Cassandra relies on queries, so use it in your favor.
Take a look up on my github project that helps you get up with multiple queries in the same table.
https://github.com/iamthiago/cassandra-phantom

Specified cast is not valid.linq query c#

I have a table name LibraryInfo with these columns
[libraryId] [smallint] IDENTITY(1,1) NOT NULL,
[libraryName] [nvarchar](200) NOT NULL,
[mId] [smallint] NOT NULL,
[description] [nvarchar](300) NULL,
[updatedBy] [int] NOT NULL,
[updatedAt] [datetime] NOT NULL
I have designed a dbml file to access this table and create a method as follows:
public List<LibraryInfo> GetLibraryInfos()
{
var context = new BookDataClassesDataContext(){ ObjectTrackingEnabled = false };
return context.LibraryInfos.ToList();
}
when I call this method 'return context.LibraryInfos.ToList();' shows me 'specified cast is not valid'.
Is there anyone to help me.
You probably changed one of the column data types in your table or view after importing the table/view into your linq model.
Just re-import it so the data types of the auto generated model are the same as the db structure.
The problem seems to be related to the data type you are using. I recommend to use smallint rather than int. I had a similar some time ago, and later realized that querying tables with "int" data type causes the exact same problem. I changed int to Int16 and the problem was solved.
My former answer was obviously not correct. But:
You seem to have a mismatch of types here. ToList() on the context.LibraryInfos table would return a list of LibraryInfos objects (List<LibraryInfos>) instead of List<LibraryInfo>. So either your method needs to be declared as
public List<LibraryInfos> GetLibraryInfos()
or the code that returns the items needs to be changed to
return context.LibraryInfo.ToList();
This really depends on which one you want to return.
On your comment to your question:
context.LibraryInfo.ToList(); gives me error that dbml file does not contain a definition for LibraryInfo
Obviously you only have a LibraryInfos table in your data context. This means that you need to change your method return type to List<LibraryInfos>:
public List<LibraryInfos> GetLibraryInfos()
So the method now reads
public List<LibraryInfos> GetLibraryInfos()
{
var context = new BookDataClassesDataContext(){ ObjectTrackingEnabled = false };
return context.LibraryInfos.ToList();
}
Every item you get from the table has the type that matches the table name, as the LibraryInfos table is actually a collection of items of type LibraryItems.
You may have created a LibraryInfo class just because the compiler complained it didn't exist - you need to decide whether you can delete that from your project (look in solution explorer for LibraryInfo.cs file). But you can not cast between an item from the LibraryInfos table and that LibraryInfo class.

Resources