Hibernate, one to many from different table to general table - java

Good day.
Exists three tables(test):
User (id, user_name)
Object(id, object_name)
Property(id, property_value)
User, Object contain Property, so I'd like to use a special table EntityProperties(entity_id, entity_type, property_id), where entity_id - id from User or Object, and entity_type - user or object (params for tables User, Object).
May I implement it using Hibernate 4? If yes, please suggest with annotations and how better to do it.
Thanks,
Oleg

You can create a mapped super class EntityPropertyMap which has a property object and have concrete implementations(UserPropertyMap and ObjectPropertyMap) with table per class hierarchy strategy. Examples can be found http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/inheritance.html and http://viralpatel.net/blogs/hibernate-inheritence-table-per-hierarchy-mapping/

if User is also an Object then it can be done by making User extends Object and then the problem becomes mapping inheritance which you can read more about here
If this is a one way relationship from a User to Property and from Object to property then I think it can be achieved by normal mapping (one to many) and then there is no need for the entity_type column since you'll only be querying the Property table with an entity_id in hand. This way a User object will have a field Set<Property> properties; and the same for the Object class.

Related

Mapping derived columns to POJOs with RecordMapper in JOOQ

i have a table tickets where i insert ticket and have a field createdBy which stores the UserId Integer of the creator of that record. During fetching I join with users table and concat firstname and last name and my DTO has field createdBy of the concatenated name of creator. How can i map the derived field? this is my reference https://www.jooq.org/doc/3.13/manual/sql-execution/fetching/pojos/ and I cant seem to find such a scenario provided
the issue is not the join. the issue is mapping the string createdBy derived after the join whereas in the record class generated by jooq is an Integer because in the database table i store the userId.
List<MyTickets> mytickets = create.select(....FIELDS).from(TICKETS_).fetch().into(MyTickets.class);
#Override
public Field<Integer> field9() {
return Tickets.TICKETS_.CREATEDBY;
}
In my answer, I will assume that your computed column is going to be called CREATED_BY_NAME, not CREATED_BY, which is a name that's already taken, and to avoid confusion.
If this is something you do frequently, you have a few options that could be interesting to you:
Use views to generate this alternative CREATED_BY_NAME column. A lot of databases can insert into / update views as well, so you won't have a big penalty in using views to replace your tables. To your client logic, the origin of this column will be transparent. If you want to work with UpdatableRecord, you will have to tell jOOQ's code generator what the view's underlying primary key is using the synthetic primary key flag.
Similar to the above views, you could use computed columns on your tables, using the GENERATED ALWAYS AS ... syntax (or whatever your dialect uses for the syntax). Not all dialects support this, but it is a nice feature that turns tables into views without the extra view object.
If you want to keep computing this column manually in your jOOQ code, you could either write your own DTO / POJO objects, or extend the code generator with a custom code section, where you generate the relevant attribute / getter / setter. This approach only works for mutable POJOs, as you cannot modify the constructor of an immutable POJO.
You can also specify a base class for all of your affected POJOs and inject that base class using a generator strategy (programmatic or configurative). The base class could then implement all the getters / setters for columns like CREATED_BY_NAME.
You can also use structural typing instead. You don't have to map all the columns into your POJO. You could also map some columns into your generated POJO (excluding CREATED_BY_NAME) and map the CREATED_BY_NAME column separately. Just keep a reference to your jOOQ Result and/or Record, and perform several map / intoXYZ() calls on it.

Enum with no ordinal key in a many-to-many relationship

Many of the answers to this question advise not to use ordinals, but just to have a single column with the value of the enum when mapping it to a table in DB.
Is this still a safe approach if I'm going to use this enum-mapped table in a many-to-many relationship?
More detailed, I have a table Car and a table Extras, that I'm modelling as an enum. Then I have a table cars_extras, that holds the nxn relationship and has three columns: id, car_id and extra_id, but I'm not sure if this is a good idea.
You are enforcing the enumeration in two places: in your code as an enum and in the database as a foreign key.
This will ensure that if someone modifies the data directly in the database, they will not accidentally misspell an enum value, but also makes it easy for the programmer to see the valid values.
I have seen people use this approach and then also add a validation step on startup that ensures that the enum table in the database has the sames values as the enum class. It halts with an error if they don't match.

Sql to object, many to many with field

I am working on a little website. The database was created and we need to create objects from sql now.
Usually, in "Many to many" relation, I use a list to represent this relation. (List of ingredient in recipe, and if I need, a list of recipe in ingredient).
But I don't know what is the best way when the junction table contain field.
For example with theses tables:
###### #################### ##########
RECIPE INGREDIENT_IN_RECIPE INGREDIENT
id id_ingredient id
name id_recipe name
quantity
other
Is there a best way to create object from this sql?
I don't know if:
I need to create an third object "IngredientInRecipe". And list it on recipe/ingredient?
Maybe create fields quantity/other in ingredient and use it only when I want to handle ingredient as "ingredientinrecipe"?
Or create a Subclass of Ingredient with quantity/other?
Maybe I'm totally wrong and I just have to create list in recipe and use sql query or array for other things but I'm little bit lost.
This is a simple association class and you would model it like this:
You concrete object model with single tables it pretty fine.
The answer here is based on the question is the INGREDIENT_IN_RECIPE an entity by itself, or is it just a relational table to create the many to many in the db.
Currently, INGREDIENT_IN_RECIPE contains additional information, that is really important and further specifies the relation between RECIPE and INGREDIENT, so this qualifies it is a proper entity.
IMHO, the best way here is to create a entity class for the INGREDIENT_IN_RECIPE table and list it on the RECIPE entity class at least. You need to check if the relation from the INGREDIENT entity is really needed and useful.

Mapping class to a table without a table name

I have many tables in my DB with exactly the same structure: same columns names and types.
The only difference between these tables is the their names (which I can only know in runtime).
I would like to create a mapping of a class to a table but giving the name of the table only during runtime (no static #Table annotation).
Is it possible?
Is there any other way to achieve my goal?
Directly - no. Because this is not a regular use-case. Normally you should not have dynamcally-generated tables. It is a valid use when you move some records to an archive table (or tables), but otherwise avoid it.
Anyway, you can make that work: make a native query, and map the result to your non-entity object. You will be able to select from any table and transform the result to an object. However, you can't insert or update that way.
Don't think associating or changing the table mapped to an entity dynamically is possible.
You can check #MappedSuperClass, which will allow you to define all fields in a class once and inherit them, so that there is no repetition and entities are empty class with mappings.
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e1168
If you know the table name dynamically you can always instantiate the mapped class accordingly.

Hibernate: #UniqueConstraint Across Multiple Tables?

I have a data model in which a number of entities inherit some common attributes from a single superclass entity. I am using InheritanceType.JOINED on the superclass, which causes Hibernate to create a single table for attributes defined in the superclass, with subclass tables containing only columns that are added by the subclass (so to load the attributes for a subclass instance, a join is performed between the two tables). That is all working fine.
What I'd like to do, however, is specify a unique constraint that includes fields in both the subclass and superclass tables. For instance, say that my superclass entity is something like:
Thing: {id, name}
...and then I have some subclass entities like:
Company: {address} //inherits 'id' and 'name' from 'Thing'
Employee: {company} //inherits 'id' and 'name' from 'Thing'
...and I want to configure Hibernate to automatically enforce that a given Company cannot have two Employee's with the same name. The company field is in the Employee table, but the name field is in the Thing table, so is there any way to get Hibernate to enforce this constraint, or do I need to do it programmatically whenever I add a new Employee?
If it's not possible in the Database it won't be possible with Hibernate. You can't create one constraint on multiple tables with SQL so neither in Hibernate.
You could work around this by creating a new Entity holding only the company and employee id and setting a unique constraint on those 2 fields but I would recommend enforcing this programmatically.
You could not use InheritanceType.JOINED, then everything ends up in a huge table, and you could write your constraint. As said before: What you want is just not possible in a relational DB.

Categories