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.
Related
I am new to ORM and got stuck on the following issue (simplified for the discussion here):
I am modelling a tournament, with competitors and disciplines. Both have their own entity class. Competitors compete in each discipline exactly once, and receive a score. As long as a competitor has not yet competed in a given discipline, there is no score.
Data Model:
A straightforward DB design would be a scores table with foreign keys to both the competitors table and the disciplines table. That is, I would set up two one-to-many relationships, plus integrity constraints on the foreign keys - I cannot delete a competitor or a discipline as long as there are scores that reference either one.
But how do I map this 2D Array (competitors/disciplines) onto my classes? I am using Java and Hibernate.
My current solution is to put a collection of scores into the Competitor entity class, and similarly for the Disciplines class. This creates a bidirectional relationship with a join table for each of the two entity classes. Is this the recommended way to do the mapping?
It does map the relationship form the perspective of each domain class, but it misses out on the 2D array structure. I want to output the entire array - on a UI, for example - with rows for competitors, columns for disciplines, and the scores in the corresponding table cell. Building such an output from the entity classes as just described is tedious and requires (a) to iterate through the competitor collection and then (b) look up the corresponding discipline - or the other way around.
Ideally, I would like to have a hash map with two keys, like the Guava Table, or a nested hash map. I suppose that there is no native Hibernate mapping for this kind of advanced collection. But maybe there is a best practice how to implement it using custom queries?
But how do I map this 2D Array (competitors/disciplines) onto my classes? I am using Java and Hibernate. My current solution is to put a collection of scores into the Competitor entity class, and similarly for the Disciplines class. This creates a bidirectional relationship with a join table for each of the two entity classes. Is this the recommended way to do the mapping?
IIRC, an implicit join table doesn't allow to add the score. Even if it did, I would't like it as the scores are actually the main information. So I'd go for an explicit table.
class Score {
#ManyToOne(optional=false)
Competitor competitor;
#ManyToOne(optional=false)
Discipline discipline;
}
This should provide everything you need. You may also want a Set<Score> or even Map<Discipline, Score> in the class Competitor (and vice versa in the other class), but you may not need it. The mapping would probably use #ManyToMany(mappedBy="competitor") and #MapKey... I haven't used it for long as I found out I don't really need it.
Ideally, I would like to have a hash map with two keys, like the Guava Table, or a nested hash map.
Using the default #ManyToOne(fetch=EAGER), the needed competitors and disciplines get fetched automatically using a JOIN. I'm afraid, a List is all you can get, but iterating it once and filling a Guava Table is trivial:
list.stream()
.forEach(score -> table.put(score.competitor, score.discipline, score));
Just don't forget that the entities are mutable but mustn't be mutated when used as keys. Obviously, you should only fetch the entities you need rather than filtering the Table. However, once you have the Table, you can use all its operations at will; Hibernate won't help you here anymore, but you don't need it (and you don't want to hit the DB again).
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.
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.
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.
I'd like to explore Hibernate and used it in my project instead of JDBC.
My table design is highly normalized.
Suppose, I have this use case: Each insurance applied by a customer has one associated rateplan. Usually, in RDBMS this is implemented using two tables like below.
Table Insurance:
id long;
accountHolder varchar;
ratePlanId int; -->Rate Plan Id is Foreign Key to the RatePlanTable
Table RatePlan:
ratePlanId int;
ratePlanDesc varchar;
discountRate double;
Now, my question is..does this qualify as a onetomany relationship?
Most of the examples that I am seeing on the net regarding onetomany, involves some sort of collections (e.g An Order has a list of products). And when represented in class is translated below, which I think is really a one to many case?
public class Order{
private List products;
}
But how about my case? I don't think that it is a onetomany or I am just mislead by the examples?
How can I do a hbm mapping for my two classes? In my case, I would create two class to represent the two tables, but I am not sure how the hbm.xml would look like for the two class.
Yes, it is a one to many relationship, in that one rate plan is associated with many insurance policies. In entity traversal, when you would go from the Policy, you would get one Plan object, and conversely, from a Plan object, you would get a list of Policy objects.