jpa multiple bidirectional many to one relationship to the same field - java

I have a problem i hope someone can help me solving.
My system has got an entity "Product". On a product it should be possible to set "replacement products" (products that are supposed to be sold instead of the original product). We have two types of replacement. On a product, i need to be able to set either none, one of them or both types of replacement product. But, only one product should be set per type. In addition to this, i want to be able to look at a product and get a list of other products that has this product as their replacement product.
Short version:
Product -> replacement (two types, one of each)
Product -> list of
products that it replaces (of both types of replacement)
My solution this far has been to create an abstract class ReplacementProduct with subclasses(one for each replacement type), with discriminatorvalues.
The replacementproduct table in the database has the following fields:
id, replacementproduct, replacementType
Further, i have placed two fields on the Product entity (instances of the subclasses for replacement types). Like this i have obtained a one way link from product to another product with a replacement type.
My problem is to make this link go both ways. As I said, I want to be able to get a list of products with the Product in question as their replacement product.
Is this possible without using a lot of java logic?
I'm open to any suggestion.

Sounds like a bidirectional ManyToMany is needed between products. The owning side would setup a mapkey mapping, using the type as the key. The other side doesn't need a key, and would reflect all the products it can replace.
This is described here
http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Map_Key_Columns_.28JPA_2.0.29

Related

java object querying ( applying SQL logic on List of java objects)

I have a Employee object for example, Employee contains several fields (300+) like name, department, salary, age, account, etc.
Entire Employee table data cached into java List object , which contains 2+ million records.
Requirement
user can search on any filed presents in Employee object like employee name like Sehwag and age > 30 or salary > 100000, Based on user search we have to show filtered list of Employee list.
due to performance issues we are not querying DB, we want to apply the user search criteria on cached java List object earlier
is there way api / frameworks / any other solution where we can query on java objects?
below approach I am trying but I am feeling not a good approach
Iterating the Employee list and applying condition user search criteria on employee object, to know the user selected search criteria among 300 fields is challenging, written a lot enum mapping logic and some additional logic for every filed to make it work.
with current requirement it may works but thinking to use api or framework or better way to solve the requirement!
thanks in advance for your help.
First of all. If you either don't want or don't have chance to change the existing solution, take a look at querydsl.
There is a querydsl-collection module which fits exactly with your need. See more at http://www.querydsl.com/ and http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s08.html
However, if you have a chance to review/rebuild the solution, you should consider something more appropriate for large volume querying. I suggest you exploring more about nonsql databases (mongodb) or indexing tools such as lucene or elasticsearch which adds a RESTFul layer on top of lucene.
I hope it helps.
tried CQEngine's SQL based queries https://github.com/npgall/cqengine suits to my requirement,
below are some useful links
https://dzone.com/articles/getting-started-cqengine-linq
https://mvnrepository.com/artifact/com.googlecode.cqengine/cqengine

Java - Data Structures

I came across a Java Data Structures task. I'm looking for a confirmation that I understood it correctly and that my approach is right.
The task:
A product can have many different types of attributes, and they can vary between products, e.g. a Bike can have the following attributes: {price, color, size} and the product Kitchen table: {price, width, depth, height}. Product Attributes are organized in a hierarchical group structure, where a Product Attribute Group can contain one or several Product Attributes and/or Product Attribute Groups.
Write the code needed in java to handle the above described products and a print function that prints the data in such a way that it is clear which attributes belong to which product and which attribute group if any.
There was an image attached with notation:
Image
Figure 1: Note that the order is important. In the figure above Attributes 1, Attribute 3 and Attributes 2 all belong to the Product Attributes group.
So my approach would be to create an abstract Product class, and then make two subclasses(Bike, KitchenTable) extending from Product class. Is it correct? Or is it about something entirely different?
Please have a look at the Composite Pattern.
The composite pattern describes a group of objects that is treated the same way as a single instance of the same type of object.
This matches your task to have product attributes that have to be organized in hierarchical groups.

Is there a library to group list of entities by several attributes

Assume there's a structure Pay with attributes: category, location, department, sum.
Having a collection of such entities I want to group it by category and location to get such a structure:
category - location - collection of Pays
There's a Guava Multimaps.index() function, but it works only for one-level grouping. And I need 2+.
Doesn't matter what type this structure will have - some Map<Map<Map>> implementation or smth else.
I just don't want to write multi-iteration code. Hope there's a library for such operation. Do you know one?
P. S. Great if works on Java 7.

Should I use a nested enum?

Say I need a data structure in Java involving one set of categories, each with one set of subcategories. For example, let's say the main category is 'brand' (like, of a product) and the subcategory is 'product'. I want to be able to map the combination of brand+product to a piece of data e.g. a price.
I'd like to use an enum type for both 'brand' and 'product' if they were on their own, because
Brand+product has only a small, single piece of data tied to it (the price)
I need to refer to them many times throughout a reasonably large program, so the chance that I'll mistype any string literal keys I assign to them is basically one.
However, the number of brands/products is too large to have a single enum for each brand/product combination (around twenty brands each with ten products and a good chance of adding more later). I'd like to be able to use the structure like this:
getPrice(APPLE.IPOD)
getPrice(APPLE.MACBOOK)
getPrice(HERSHEYS.PEANUT_BUTTER_CUPS)
Should I use some sort of nested enum? If so, how would that be implemented?
Bonus information: I've spent a bit of time googling 'java nested enum' but haven't come up with anything. The problem with structures like the first one in the ticked answer here or thelosts's answer here is that I have too many categories all exhibiting the same behavior to write out very similar enum definitions so many times.
I wouldn't use an enum for this.
I would suggest you load this information from a file or database. Java is not a good place for storing large amounts of data.
You could add a getter and setter to the Brand enum that allows setting a Product enum, but that will not enforce that a Product is actually manufactured by that Brand. Besides, there is ever only one instance of each enum value -- so you could never have APPLE.IPOD and APPLE.IPAD. You either need a single enum type that represents the Cartesian product, or you need to load your values from a data store like Peter Lawrey suggests.

Multilingual fields in DB tables

I have an application that needs to support a multilingual interface, five languages to be exact. For the main part of the interface the standard ResourceBundle approach can be used to handle this.
However, the database contains numerous tables whose elements contain human readable names, descriptions, abstracts etc. It needs to be possible to enter each of these in all five languages.
While I suppose I could simply have fields on each table like
NameLang1
NameLang2
...
I feel that that leads to a significant amount of largely identical code when writing the beans the represent each table.
From a purely object oriented point of view the solution is however simple. Each class simply has a Text object that contains the relevant text in each of the languages. This is further helpful in that only one of the language is mandated, the others have fallback rules (e.g. if language 4 is missing return language 2 which fall back to language 1 which is mandatory).
Unfortunately, mapping this back to a relational database, means that I wind up with a single table that some 10-12 other tables FK to (some tables have more than one FK to it in fact).
This approach seems to work and I've been able to map the data to POJOs with Hibernate. About the only thing you cant do is map from a Text object to its parent (since you have no way of knowing which table you should link to), but then there is hardly any need to do that.
So, overall this seems to work but it just feels wrong to have multiple tables reference one table like this. Anyone got a better idea?
If it matters I'm using MySQL...
I had to do that once... multilingual text for some tables... I don't know if I found the best solution but what I did was have the table with the language-agnostic info and then a child table with all the multilingual fields. At least one record was required in the child table, for the default language; more languages could be added later.
On Hibernate you can map the info from the child tables as a Map, and get the info for the language you want, implementing the fallback on your POJO like you said. You can have different getters for the multilingual fields, that internally call the fallback method to get the appropiate child object for the needed language and then just return the required field.
This approach uses more table (one extra table for every table that needs multilingual info) but the performance is much better, as well as the maintenance I think...
The standard translation approach as used, for example, in gettext is to use a single string to describe the concept and make a call to a translate method which translates to the destination language.
This way you only need to store in the database a single string (the canonical representation) and then make a call in your application to the translate method to get the translated string. No FKs and total flexibility at the cost of a little of runtime performance (and maybe a bit more of maintenance trouble, but with some thought there's no need to make maintenance a problem in this scenario).
The approach I've seen in an application with a similar problem is that we use a "text id" column to store a reference, and we have a single table with all the translations. This provides some flexibility also in reusing the same keys to reduce the amount of required translations, which is an expensive part of the project.
It also provides a good separation between the data, and the translations which in my opinion is more of an UI thing.
If it is the case that the strings you require are not that many after all, then you can just load them all in memory once and use some method to provide translations by checking a data structure in memory.
With this approach, your beans won't have getters for each language, but you would use some other translator object:
MyTranslator.translate(myBean.getNameTextId());
Depending on your requirements, it may be best to have a separate label table for each table which needs to be multilingual. e.g.: you have a XYZ table with a xyz_id column, and a XYZ_Label table with a xyz_id, language_code, label, other_label, etc
The advantage of this, over having a single huge labels table, is that you can do unique constraints on the XYZ_labels table (e.g.: The english name for XYZ must be unique), and you can do indexed lookups much more efficiently, since the index will only be covering a single table at a time (e.g.: if you need to look up XYZ entities by english name) .
What about this:
http://rob.purplerockscissors.com/2009/07/24/internationalizing-websites/
...that is what user "Chochos" says in response #2

Categories

Resources