How to maintain the table relationship - java

I am creating a pojo class in spring mvc. I am trying to have a product class which will have n number of products and each of which can follow under different categories.
As the categories of these products will remain the same. Let say it will have only 5 different categories by default.
Now I have to relate the each product to related categories.
Question:
I the above case how can I relate the product to different categories?
Which relationship will be suitable in hibernate.(One to many or many to one)?
How this relationship can be designed?

As per your requirement I can think of 2 particular cases below:
If a category can have n number of products but a product can belong to only one particular category then relationship from Category to Product will be 1 to Many.
If a category can have n number of products and also a product can belong to n number of categories then relationship between category to product will be many to many in which case you also need to have a third table which will be a JOIN table.

Related

JPA ManyToMany and unidirectional deletions

I've the following relationship:
class Product { // 10000s many of them
#ManyToMany
List<Category> categories; //usually 0-5
}
and
class Category {
...with no back link...
}
now if I delete a category and then I load a product that has that category I will get an error that contains:
update or delete on table "categories" violates foreign key constraint (...) is still referenced from table product_category
I've seen a number of answers and tutorials, but the problem is that many do propose to add Product as a bidirectional relationship in Category, then before removing a category I will go through all Products and remove that particular category. But products are thousands here and the operation will be too long.
This could be so simple by using normal SQL, but I'd like to keep the automatic loading of of categories and the mapping of the properties. Is there a lightweight way to automatically do this without keeping a list of products in each category?
What you're trying to do does not make lot of sense IMO.
You want to keep unidirectional relation but want a way to delete the other side directly.
But I understood that the problem was the huge dataset (category -> product).
One way to solve this would be to mix in the same transaction a JPQL(to delete the category) and a native query (to delete rows from the join-table).
em.createNativeQuery("delete from product_category where category_id = ?").setParameter(1, category.getId()).executeUpdate();
em.remove(category);

Joining multiple tables and using AliasToBean Transformer

I have 6 different tables and the first table has a child table and the second table is the parent for the second one(First to second tables all one to many relationships). So this continues to 6 tables. Something like the main table would be college and child will be Student and then for Student we have Subject as child tables and for Subject, we have chapters to as a child.
Can some help me with an example of how can I map this multiple join query to a BO using AlisastoBaean transformer. The reason I am going with this approach is that
1) I have these tables used everywhere and cannot use lazy or eager loading
2) I just require two or 3 columns form each table.
3) And few columns have clob data type.

Limit of 1 write per sec per a Single Entity Group?

I have searched this enough & haven't found the answer yet. So I am asking.
According to the Google cloud datastore doc.
There is a write throughput limit of about one transaction per second
within a single entity group.
Now let's just say I have an Entity User & another entity Cars. They have a common parent. So User+Car+Their_Parent is one entity group. Right?
Let's assume In the datastore User & Car have a million instances/rows each.
If I fire a transactional query to update instance/row in the datastore.
My confusion is how many Entity group instances get locked for applying the write limit for Google DataStore?
A. User + Car (Comprehensively with twenty million instances)
B. Just 1 instance of User + Car? (1 user row & 1 car row)
In database parlance, User is an Entity Kind/Table. So does the entire
Table/Kind gets locked for 1 write operation or just one instance/Row
gets locked for 1 write operation?
If A is the case does that mean for 1 write, all 20 million rows of User+Car entities will be locked? That's crazy. What if I have to update all 20 million rows. If a write operation is updating just 1 row, will 20 million rows require 20 million secs to avoid any contention?
an entity group is a set of entities connected through ancestry to a
common root element. The organization of data into entity groups can
limit what transactions can be performed:
See the "Python" docs here. Surprised it wasn't somewhere in your Java documentation link
Finally found the answer here data store article
In the example above, each organization may need to update the record of any person in the organization. Consider a scenario where there are 1,000 people in the “ateam” and each person may have one update per second on any of the properties. As a result, there may be up to 1,000 updates per second in the entity group, a result which would not be achievable because of the update limit. This illustrates that it is important to choose an appropriate entity group design that considers performance requirements. This is one of the challenges of finding the optimal balance between eventual consistency and strong consistency.

JPA Single foreign Key ID to refer to two (or more) tables

Simple question really. This is using JPA on Java and what I what to do is to have a table with and column which can refer to one of two tables. To make this clearer I can have a 'User' table and a 'TempPerson' table. I don't want to pollute my User table (as I use it for security as well, plus has other info as well). Now lets say I have a third table called 'Game'. Now when someone stars a game against someone, they can play against someone in the system already ie. User or someone where they can type a name and new entry for TempPerson is created and used. So the game for player2 (or player1) will be a mapped id to either User.id or TempPerson.id. Now I understand that a determining column may need to be placed into Game to determine what the Id is for but I hope JPA will cater for it somehow. Any ideas will be helpful, i could use inheritance but not sure about it.
Here is another example:
Lets say I have a table which holds information about images => id, resolution, width, height, location, bucket .... id_in_the_table_where_used, table_name_of_where_used. Now, this one table can hold the images for profiles, places, etc... and the profiles, places will have an id referring to the images table, but I also would like the images table to have an id back to where the images is used, which table and which id is using it.
It almost I am asked i 'one to many tables' solution. Although I could have many in between tables etc... Seems overkill to so something quite simple, although many DBAs may be cursing this idea. It does minimise queries, number of tables etc...
Thanks in advance
It is possible to use single FK to target multiple tables. You would have to use #JoinColumn for that
#Entity
public class User{
#OneToOne
#JoinColumn("universalId", targetEntity=Avatar.class)
private Avatar
#oneToMany
#JoinColumn("universalId", targetEntity=Log.class)
private List<Log> logs;
}
This would use universalId column of User's table to lookup related records from Avatar and Log tables
This however is rather anti-pattern, causing a lot of consequences when for example universalId will have to be changed etc. 1 column = 1 FK - go that way.

Should I iterate over hibernate collections to find an entity, or use criteria

What is the convention for this? Say for example I have the following, where an item bid can only be a bid on one item:
public class Item {
#OneToMany(mappedBy="item", nullable="false"
Set<ItemBid> itemBids = new HashSet<ItemBid>()
}
If I am given the name of the item bidder (which is stored in ItemBid) should I A) Load the club using a club dao and iterate over over the collection of it's itemBids until I find the one with the name I want, or B ) Create an ItemBid dao where the club and item bid name are used in criteria or HQL.
I would presume that B) would be the most efficient with very large collections, so would this be standard for retrieving very specific items from large collections? If so, can I have a general guideline as to what reasons I should be using the collections, and what time I should be using DAO's / Criteria?
Yes, you should definitely query bids directly. Here are the guidelines:
If you are searching for a specific bid, use query
If you need a subset of bids, use query
If you want to display all the bids for a given item - it depends. If the number of bids is reasonably small, fetch an item and use collection. Otherwise - query directly.
Of course from OO perspective you should always use a collection (preferably having findBy*() methods in Item accessing bids collection internally) - which is also more convenient. However if the number of bids per item is significant, the cost of (even lazy-) loading will be significant and you will soon run out of memory. This approach is also very wasteful.
You should be asking yourself this question much sooner: by the time you were doing the mapping. Mapping for ORM should be an intellectual work, not a matter of copying all the foreign keys onto attributes on both sides. (if only because of YAGNI, but there are many other good reasons)
Chances are, the bid-item mapping would be better as unidirectional (then again, maybe not).
In many cases we find that certain entities are strongly associated with an almost fixed number of some other entities (they would probably be called "aggregates" in DDD parlance). For example invoices and invoice items. Or a person and a list of his hobbies. Or a post and a set of tags for this post. We do not expect that the number of items in a given invoice will grow over time, nor will the number of tags. So they are all good places to map a #OneToMany. On the other hand, the number of invoices for each client will be growing - so we would just map an unidirectional #ManyToOne from client an invoice - and query.
Repositories (daos, whatever) that do queries are perfectly good OO (nothing wrong with a query; it is just an object describing your requirements in a storage-neutral way); using finders in entities - not so. From practical point of view it binds your entities to data access layer (DAOs or even JPA classes), and this will make them unusable in many use cases (GWT) or tricky to use when detached (you will have to guess which methods work outside session). From the philosophical point of view - it violates the single responsibility principle and changes your JPA entities into a sort of active record wannabe.
So, my answer would be:
if you need a single bid, query directly,
if you want to display all the bids for a given item - fetch an item and use the collection. This does not depend on the number of bids per item, as the query performed by JPA will be identical as a query you might perform yourself. If this approach needs tuning (like in a case where you need to fetch a lot of items and want to avoid the "N + 1 selects problem") then there is plenty of ways (join fetch, eager fetching, hints) to make it right, without changing the part of the code that uses getBids().
The simplest way to think about it is: if you think that some collection will never be displayed with paging (like tags on post, items on invoice, hobbies on person), map it with #OneToMany and access as a collection.

Categories