OpenJPA: several #Embedded vs one #ElementCollection - java

I am trying to decide which annotation to use. Can you offer your opinion?
What I have now:
#Entity
public class Balance {
#Embedded
private Amount amountAtm;
#Embedded
private Amount amountBranch;
#Embedded
private Amount amountVault;
}
#Embeddable
public Amount {
private BigDecimal debit;
private BigDecimal credit;
}
What I want to change it to:
#Entity
public class Balance {
#ElementCollection
private Map<AmountType, Amount> amounts;
}
public enum AmountType {
ATM, BRANCH, VAULT;
}
The Amount would stay the same.
The reason for this change, is because the amounts inside the balance are conceptually a collection. I either display/change all of them at the same time, or none at all. So, I treat them as a group.
Questions:
Right now the amounts are stored in the same table as the balances (I override column names, this is not shown in the code). However, if I make this change there is NO WAY I can store all this data in one table. I would have to store amounts in a separate table. Is this correct?
Considering that now I will have to make JOINs in SQL, etc. How will this affect the performance? Let's say I am using Oracle 11g and I have 100,000 balance records (and therefore 300,000 amounts). Will I notice the slowdown in the application after the change?

Yes, it's correct.
Impossible to say without testing. I don't see how it could be faster than storing the six fields in the table directly.
What I don't understand is why you're not satisfied with your three fields. If you want to be able to have a Map<AmountType, Amount> getAmounts() method (and the corresponding setter) in your entity, nothing prevents you from adding it and implementing it yourself:
public Map<AmountType, Amount> getAmounts() {
Map<AmountType, Amount> result = new HashMap<AmountType, Amount>(3);
result.put(AmountType.ATM, amountAtm);
result.put(AmountType.BRANCH, amountBranch);
result.put(AmountType.VAULT, amountVault);
return result;
}

Related

Update one parameters of many of objects - the best way

I have a situation to deliver solution for functionality of update one property of many objects. The point is that is possible to update any property. For example
class Book {
private String name;
private Long number;
private LocalDate date;
private SomeEnum name;
private boolean someFlag;
}
Possible is to update only one field at a time, but each field is available to update.
Of course I can create new filter class with each field and send it with given parameter I'd like to update, but I thinking about more elegant solution. More generic.
I have to List get objects by ids from database, update and save all with updated field.
What do You think this could be done. Is possible to create filter class with one generic field depend on what variable user give to update? What is the best practice to do something like that ? What is you experience ?

Storing ArrayList object data in mySQL Database

I am creating a web application that has a User object and each User object has an ArrayList of objects (Food) that need to be stored into a table in a mySQL database. I want to store the entire ArrayList into a single column. Would it be better to store it as a Json? Or should I just create a table for each User that stores the individual items of the ArrayList? The only problem I have is that the data would edited quite frequently.
EDIT: I have tables for both Users and Food. The idea is that Users add from the Foods from the Food table to their ArrayList and then I want to store that ArrayList in something.
public class User{
private int id;
private String username;
private List<Food> FoodList = new ArrayList<Food>();
}
public class Food{
private int id;
private String name;
private double protein;
private int calories;
...
}
As #ayrton mentions, creating (at least) two tables is a good idea (one for Users and one for Foods).
Definitely don't create a table per User
As #NeplatnyUdaj mentioned, a join table (where you map Foods to Users) might be warranted (or it could be overkill, depending on your needs).
Given the details you've described, JSON is almost certainly not the best approach (this isn't true in all situations, but if you were in such a situation, I'd probably suggest you consider a different type of database).
(Welcome to SO, btw!)

Hibernate suitable inheritance strategy

This is the parent class
#MappedSuperclass
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class APostCommon extends Actionable {
private static final long serialVersionUID = 1L;
#Column(name = "TITLE")
private String title;
#Lob
#Column(name="DESCRIPTION")
private String description;
//omitted others for purity
}
This is a child class
#Entity
#Table(name="QUESTION")
public class Question extends APostCommon {
private static final long serialVersionUID = 1L;
#Transient
private List<Answer> answers;
#Column(name="FOLLOW_COUNT")
private Integer followerCount;
#Column(name="ANSWER_COUNT")
private Integer answerCount;
//omitted others for purity
}
Answer only differs from the superclass by including the questionId field
#Entity
#Table(name="ANSWER")
public class Answer extends APostCommon{
private String questionId;
//omitted others for purity
}
Which data model is suitable for me. Should I use InheritanceType.SINGLE_TABLE or TABLE_PER_CLASS. Whats happen when there is millions record in future.
As i was preparing for JPA Certificate, these are my cherry picked notes on both strategies:
Single Table Strategy
The approach may be more wasteful of database tablespace, but it does offer peak performance for both polymorphic queries and write operations.
The SQL that is needed to issue these operations is simple, optimized and does not require joining
Pros in your case: Maybe your design will not be nice and normalized but you will spare yourself a lot of headache regarding performance, and also your queries will be a lot simpler especially if you are expecting to have millions of records for Questions and Answers.
Cons in your case: I am guessing that Question and Answer will have a lot in common, but also, as the time goes and the table grows, a lot of distinct properties / columns. You might end up with one of those bloated tables that hold every possible peace of data and is unmaintainable at some point (not once i had to had approval of an entire department and days of testing to add a single index to one of the columns to a table like that).
Joined Strategy
Mapping a table per entity provides the data reuse that a normalized data schema offers and is the most efficient way to store data, that is shared by multiple subclasses in the hierarchy.
Pros in your case: with time, the number of additional distinct columns between Question and Answer tables is not a problem as your schema is nice and normalized, therefore each of those has a logical place. The design is clean, clear, maintainable and scalable (possibly you might need to add more abstraction to specialized Questions and Answers).
Cons in your case:
with millions of rows for questions and answers, you will need at least one additional join for basic queries, though if you keep it normalized as the columns / features grows, the minimal number of joins will be higher than that.
Conclusion:
Initially i was leaning towards the Single Table, but as i give myself a bit of time, it made realize that would be a 'lazy' decision (put everything in one bag and forget about design).Joined Tables seems more of a mature decision as you need to think about your indexing strategy, into how many tables you should normalize (and which groups of data) and finally coming up with efficient queries, batch statements.
Decision is up to you, but if you go for the joined strategy you will definately increase your skillset as it will be more demanding.

hibernate jpa update two field on persisit and read from one only

one quick question for java hibernate/jpa users.
I have two tables(entities) A and B with relations as A has many B (one to many). Entity A has Set of values B in java.
Due to read performance issue i want to implement master-details denormalization, so i want to store raw Set object (maybe serialized) directly in entity A (because many to one relation cost me to much cpu time because of read by jpa (update is not an issue)).
The problem is, can i achieve something like that getBs always returns me denormalized object (so its fast) and addB adds new B to Set and updates denormalized object with new raw data that is prepared for faster read?
its oracle db.
entity example:
class A {
Long id,
String name;
Set<B> arrayOfBs;
byte[] denormalizedArrayOfB;
getArrayOfBs() {
return (Set<B>) denormalizedArrayOfB;
}
addArrayOfBs(B b) {
//persist b
// update and persist denormalizedArray with new b
}
//getters and setters...
}
class B {
Long id;
A reference;
String x;
String y;
//getters and setters...
}
That's complicated. There are better approaches to your problem:
You can simply replace the one-to-many association with a DAO query. So whenever you fetch the parent entities you won't be able to get the children collection (maybe they are way too many). But when you want to get a parent's children, you simply run a DAO query, which is also easier to filter.
You leave the children collection, but you use an in-memory cache to save the fully initialized object graph. This might sounds like a natural choice, but most likely you're going to trade consistency for performance.

Object formation with relationships(JDBC)

There are 3 entities (which matches tables):
public class Enterprise{
private long id;
private String name;
private List<Department> departments;
//getters()/setters()
}
public class Department{
private long id;
private String name;
private List<Employee> employees;
//getters()/setters()
}
public class Employee{
private long id;
private String name;
private List<Department> departments;
//getters()/setters()
}
ENTERPRISE---|OneToMany|---DEPARTMENT---|ManyToMany|---EMPLOYEE
Can someone write method on JDBC :
List<Enterprise> findAll();
The connection, statements, queries, etc. can be ignored. The main difficulty is to set all references on the correct objects (for example, to avoid:
enterprise.getDepartments().get(1).getEmployees().get(1).getDepartments() == NULL) .
EXAMPLE (The beginning of method):
List<Enterprise> findAll(){
ResultSet rs = executeQuery(SELECT_ALL_ENTERPRISES);
List<Enterprise> ents = createEnterprises(rs);
.........
Mapping objects to relations is not as easy as it would seem. They have been working on it for decades now, with decent results only in some scenarios. The good news is that the scenarios that work can accommodate most programs.
I suggest that you take a different approach, but first I'll give you an example that will help you understand why I suggest the different approach.
Imagine a person who wants to look up all Departments, which will require a look up of all Employees (as they are part of a Department object). Which will require that for each employee, a list of departments would need to be looked up, which would require that those departments would need a list of employees, which would ....
Perhaps now you get the idea.
So many systems that are structured like yours don't actually return full Employees when looking up departments. They return "Employee identifiers". This allows one to look up all the Departments, but it guarantees that no Employees are going to be returned, preventing an infinite loop. Then, if a person is interested enough, they can use the employee identifiers to look up individual employees, which would of course contain department identifiers.
In short, I recommend that you don't really rebuild the association at this level. I suggest that you build disconnected graphs of the object mesh, such that one can easily navigate the disconnected graph at a later time. Then, if you really must connect them, you will at least have all the data loaded without recursion before you start knitting together references.
Many ORM libraries enable you to define one to many relationships as you described. Sormula can do this. See one to many example.
What I like about Sormula is that if you name the foreign key field on the "many side" the same as the field "one side", then Sormula will deduce the relationship and no annotations are necessary.

Categories

Resources