7

How do you design a DAO class for an entity that has multiple fields?

For example for the below entity :

public class MyEntity{

    private long id;
    private int field1;
    private String field2;
    private Date field3;
    private Date field4;
    private int field5;

}

Should i create a DAO class that has update methods for each field like :

public class MyEntityDao{
    public insert(MyEntity myEntity);
    public delete(MyEntity myEntity);    
    public get(long id);
    public updateField1(MyEntity myEntity)
    public updateField2(MyEntity myEntity)
    public updateField3(MyEntity myEntity)
    public updateField4(MyEntity myEntity)
    public updateField5(MyEntity myEntity)

}

It seems like the logical thing to do but i usually see example of just a single update() method. In that case, how should the DAO determine which field is to be updated in the database? Does it just update all fields blindly, even though only 1 might have changed? Or should the entity class have flags as members to indicate which fields have changed?

faizal
  • 3,497
  • 7
  • 37
  • 62

2 Answers2

2

You just need to pass the entity to update and the DAO will automatically determine the changed fields and update them in the DB.

public update(MyEntity myEntity);

And then the DAO gets the id of myEntity and update the entity in the database.

Sebas
  • 21,192
  • 9
  • 55
  • 109
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • how does the DAO determine which fields have changed? – faizal Nov 04 '14 at 16:17
  • you say to pass just the id, but your code passes the entity object – faizal Nov 04 '14 at 16:19
  • @faizal: No you pass the entity not the id (I was wrong) and the DAO will determine the id of this entity and using it it will update the entity in the table even if you haven't changed any field. – cнŝdk Nov 04 '14 at 16:23
  • So if there 20 fields in the entity corresponding to 20 columns in the table, and my application has changed only 1 field, the DAO should simply update all 20 columns? Seems a little wasteful. – faizal Nov 04 '14 at 16:26
  • I don't think so! Honestly all I know is that when you update, the DAO takes all the entity and referring to its id makes the changes in the db without giving it the changed fields. – cнŝdk Nov 04 '14 at 16:33
  • @faizal, your own code should be able to know whether an entity has changed, if it is your choice to do so. You can keep a buffer track of entities, in entities themselves for example. Use public setters to track changes of each attribute, then compile the final update query based on the `hasChanged` result of each attribute (all this is just an example of how to proceed) – Sebas Nov 04 '14 at 16:39
  • Please also note, that some DBMS, such as Microsoft SQL Server, are smart enough to NOT UPDATE same values. So, you got that logic already implemented for you on the database side. – Matias Cicero Nov 04 '14 at 16:41
  • What if the system needs to run simultaneous updates to the same record with only a subset of columns that need to be updated? For example, process 1 needs to update Column A, but process 2 needs to update column B? Wouldn't this cause one process to overwrite the other? – Dave L Jun 26 '17 at 18:45
  • @DaveL This will be automatically handled within transactions, I think each process will have its own transaction so they won't overwrite each other, you can check [this question](https://stackoverflow.com/q/3777794/3669624) for further details. – cнŝdk Jun 28 '17 at 16:28
  • @chsdk, even if you use transactions wouldn't the second transaction overwrite the changes made by the first? Example: User 1 updates field A in the bean, User 2 updates field B in the bean, User 2 passes bean to DAO, DAO updates all fields. User 1 passes bean to DAO, DAO updates all fields. User 2's changes to field B have been lost. – Dave L Jun 28 '17 at 16:33
  • @DaveL No only affected fields will be updated in each transaction. Hibernate will handle this automatically. – cнŝdk Jun 28 '17 at 16:53
1

You should update all fields at once.

why?: It most wasteful to query for the object, then compare with the actual entity, determine which fields must be updated, create a different PreparedStatment for each combination. And finally update those fields.

Ezequiel
  • 3,477
  • 1
  • 20
  • 28
  • That would mean a whole lot of data being transferred every time, making even the smallest operation a strain on resources. – faizal Nov 05 '14 at 03:05
  • In the other way, when you are quering the entity's state you have to transfers all data from persistence layer to business layer due to make the comparison. The only case that you wouldn't need that comparisons is in a non concurrency application, or providing some kind of pesimistic locking. You have to be sure that no other thread or user has changed the entity in the persistence layer to use this approach you propose. And that scenario is so specific that should think if its really neaded to add that complexity to improve the performance. – Ezequiel Nov 05 '14 at 07:30