Possibly a simple (read dumb) question. I am in design phase of a web application - standard Spring MVC and planning on using Spring DAO support (jdbctemplate - no hibernate & no ibatis etc).
I am currently modeling my data objects for the RDBMS. What is the best practise for data types? Let's say my primary key of a table is Numeric - Do I model that in my object as Long or long? Any problem / advantage of one over another?
Gurus?
Long is nullable. So an object with a null id (in Java) can represent an object that is not (yet) persisted. You can explicitly configure Hibernate to treat it that way, and if you don't use Hibernate, it's still good practice to give you DAO methods a way of finding out whether a particular object is already in the database or not.
I prefer to have a type "Identity" that is Serializable (Comparable, Clonable etc) and which String representation is used e.g. to build URLs. Only the DAO implementation knows which exact type it is. It could be Long or it could be a combined primary key. Above the Data Access layer, the application only deals with the Identity.
If the identity is null, the object is not persisted (has no identity assigned via the persistence store).
Related
Is a Data Transfer Object the same as a Value Object or are they different? If they are different then where should we use a DTO and where should we use a VO?
The programming language we are talking about is Java and the context is - there is a web application, which fetches data from a database and then processes it and ultimately the processed information is displayed on the front-end.
A value object is a simple object whose equality isn't based on identity.
A data transfer object is an object used to transfer data between software application subsystems, usually between business layers and UI. It is focused just on plain data, so it doesn't have any behaviour.
A Data Transfer Object is a kludge for moving a bunch of data from one layer or tier to another, the goal is to minimize the number of calls back and forth by packing a bunch of stuff into the same data structure and sending it together. Some people also use it, like Michael points out in his post here, so that the classes used by one layer are not exposed to the layer calling it. When I refer to DTO as a kludge, I mean there's not a precise abstract concept getting implemented, it's a practical workaround for helping with communication between application layers.
A Value Object is something where we're only interested in its value, like a monetary amount, a date range, or a code from a lookup table. It does not have an identity, meaning you would not be concerned, if you had several of them, of keeping track of which is which, because they are not things in themselves.
Contrast Value Objects to things that do have a unique identity in your system, which are called Entities. If you have a system where it tracks a customer making a payment, the customer and the payment are entities, because they represent specific things, but the monetary amount on the payment is just a value, it doesn't have an existence by itself, as far as your system is concerned. How something relates to your system determines if it is a Value Object or an Entity.
use a DTO at the boundary of your services if you don't want to send the actual domain object to the service's clients - this helps reduce dependencies between the client and service.
values objects are simply objects whose equality isn't based on identity e.g. java.lang.Integer
DTOs and value objects aren't really alternatives to each other.
They are different, but I've even used the two interchangeably in the past, which is wrong. I read that DTO (Data Transfer Object) was called a VO ( Value Object) in the first edition of the Core J2EE Patterns book, but wasn't able to find that reference.
A DTO, which I've sometimes called a Dumb Transfer Object to help me remember it's a container and shouldn't have any business logic is used to transport data between layers and tiers. It just should be an object with attributes that has getters/setters.
A VO however is similar to a JAVA Enum and represents a fixed set of data. A VO doesn't have object identity (the address of the object instance in memory), it is identified by its value and is immutable.
Martin Fowler, talking about Data Transfer Objects (DTOs):
Many people in the Sun community use the term "Value Object" for this pattern. I use it to mean something else.
So the term "Value Object" has been used to mean DTO, but as of him (and the other posters), its use as a DTO seems discouraged.
Good detailed answer in Matthias Noback article Is it a DTO or a Value Object?
In short a DTO:
Declares and enforces a schema for data: names and types
Offers no guarantees about correctness of values
A value object:
Wraps one or more values or value objects
Provides evidence of the correctness of these values
Maybe because of lack of experience, but I would put it this way: It's the matter of scope.
DTO has word transfer in it so it means some parts of the system will communicate using it.
Value object has smaller scope, you will pass set of data in value object instead in array from one service to the other.
As much as I understood niether of them is "object whose equality isn't based on identity".
We can use a class object for transfering data to another class. what is the speciality of data transfer objects? How to create them ? Is it just like class objects?
The primary difference is that DTOs, by design, don't have any business logic in them. They're just data structures.
For instance: You might have a database in which you store "users", and if using DTOs, you might use a UserBean to store and retrieve user objects. But your business logic may have a User object (possibly derived from the bean, more likely using the bean via aggregation) that not only has the data, but additional methods for things that User can do.
I believe this should be true:
assertTrue(POJO == DTO)
The only special thing about DTO is that they should not contain any behavior.
1, The class object maybe contains too many references to other objects, thus too big to be serialized to transfer. DTO only selects the interesting parts, this can be a performance gain.
2, In Hibernate, the entity object may contain lazy-initialized references, these objects need session context to do initialization. These entity objects looks like "smart objects", DTO here convert these "smart objects" to "plain objects", because transfer "smart objects" is meaningless when the session context is no more existed.
Personally, I don't like DTO, it introduce another layer of redundant, but sometime (especially when working with Hibernate ORM) I can't live without it.
A DTO class is an ordinary Java class with a just special meaning - just like a Observer, a Factory or a Model. The name is coming from a core J2EE design pattern (the Transfer Object pattern) and the pattern proposes a common way to transfer information between a database and java-classes-based model.
In brief, a DTO is a java class where the class name maps to a database table name and each database column maps to a class attribute. Then it contains getter and setter methods.
Here is one explanation of the (Data) Transfer Object pattern.
What is the best way to convert types in a Struts2 application?
Right now I want to create a CRUD for a certain hibernate entity in my application. Say I wanted to change the Account that a User is associated with. I can just pass in the parameter user.account.id with a specific value, provided that I have all of the proper getters/setters.
This works perfectly fine when creating an object for the first time, where the account would be null. This makes ognl create a new account object, and set the id to what was passed in.
The problem happens when trying to change the encapsulated Account object. Using the same user.account.id parameter, ognl interprets this as getUser().getAccount().setId(param). Hibernate interprets this as an attempt to change the primary key.
I understand why it does this, I am just wondering if there is better way for handling this case. This is very common in our application, and I don't want to have to keep creating multiple objects and marshaling them over before I save them via hibernate.
Does anyone no a better way to solve this problem in struts2?
Type Converters for Persistence
Create a type converter for the entity and then just pass user.account, rather than user.account.id. This will invoke getUser().setAccount(account) and wont cause you the headaches.
When you update the record, just pass user.account as a hidden field in the form.
As for a widespread solution for your entities, you have a few options:
Multiple Converters
Create an abstract type converter that handles most of the logic so that you have a subclass-per-entity that is really lightweight. Register each converter in your xwork-conversion.properties.
Interface-Driven Converter
The approach that I use is that I have an interface called IdBasedJpaEntity which 99.9% of my entities implement. It defines a getId() method of type Integer. I then have a JpaDAORegistry singleton class that I create when my app starts. I register each of my entities with it and it constructs a single instance of each DAO (basically, a de-facto singleton). I have a map of entity class to DAO instance. This allows my type converter to look up the appropriate DAO instance for any given IdBasedJpaEntity, allowing me to have a single JpaEntityConverter class that works with any entity that implements the interface. This route is a little bit more work up front, but has proven highly reusable for me.
I have an entity in my system, which naturally needs an identifier so that it can be uniquely identified. Assuming the database is used for generating the identifier with Hibernate, using the native strategy, then obviously the application code is free of this responsibility of assigning identifiers.
Now, can an instance of that entity be considered valid before it is persisted and gets its identifier?
Or should I use some other strategy to assign my entities their identifiers so that it gets its identifier when its constructor is called?
That's an extensive topic, but here are two possibilities:
define your hashCode() and equals(..) contracts based on business keys. For example, for a User entity, this would be the username, rather than the auto-generated id. Thus you will be able to use the entity in collections before it is persisted
use UUID as a primary key, and handle the generation yourself. See this article by Jeff Atwood and this article demonstrating a way to use it with Hibernate
(Since you mention DDD and hibernate, take a look at this article of mine)
For a project I am working on, I need to persist a number of POJOs to a database. The POJOs class definitions are sometimes highly nested, but they should flatten okay, as the nesting is tree-like and contains no cycles (and the base elements are eventually primitives/Strings). It is preferred that the solution used create one table per data type and that the tables will have one field per primitive member in the POJO. Subclassing and similar problems are not issues for this particular project.
Does anybody know of any existing solutions that can:
Automatically generate a CREATE TABLE definition from the class definition
Automatically generate a query to persist an object to the database, given an instance of the object
Automatically generate a query to retrieve an object from the database and return it as a POJO, given a key.
Solutions that can do this with minimum modifications/annotions to the class files and minimum external configuration are preferred.
Example:
Java classes
//Class to be persisted
class TypeA {
String guid;
long timestamp;
TypeB data1;
TypeC data2;
}
class TypeB {
int id;
int someData;
}
class TypeC {
int id;
int otherData;
}
Could map to
CREATE TABLE TypeA (
guid CHAR(255),
timestamp BIGINT,
data1_id INT,
data1_someData INT,
data2_id INt,
data2_otherData INT
);
Or something similar.
I would use the standardized Java Persistence API (JPA), preferably with annotations. Regarding your requirements:
This is not required by the specification but most JPA providers (all major implementations do) support DDL generation from the mapping metadata.
EntityManager#persist(Object entity) does that.
<T> T EntityManager#find(Class<T> entityClass, Object primaryKey) does that.
As hinted, JPA is an API, you need an implementation to use it. My preference goes to Hibernate Entity Manager or EclipseLink (see this previous question).
Hibernate can help you solve all the three problems you listed.
(1) You need to annotate your entity classes so Hibernate is able to map between classes/objects to tables/rows. Hibernate uses a convention over configuration approach so it is possible to use just a few annotations and have a complete o/r mapping ready for use. You could use the hibernate.hbm2ddl.auto configuration option to instruct Hibernate to automatically validate/export and schema DDL when the session factory is first created.
(2) / (3) Hibernate has enough information about classes, database schema and mappings to allow it generate SQL statements for simple CRUD operations with minimal effort. You can fine tune how Hibernate loads and persists a tree of objects. Association mapping annotations have the fetch and cascade options that let you specify how associated objects are fetched (lazy / eager) and how operations are propagated through the object tree. Please refer to the Hibernate documentations for the details about these options.
If you are new to Hibernate, I recommend the good Hibernate documentation as reference and the book Java Persistence with Hibernate for the deeper understanding about the framework (it has very good sections about fetching and cascading).
In a typical scenario, Hibernate requires just a bit of configuration (one hibernate.cfg.xml file). You can define the mappings using XML files (no good) or annotations (the "default" option for new projects).
You tagged your question as Hibernate. Have you tried using Hibernate for this?
As long as you define well how collections should be mapped (e.g., one-to-many), I've found it generally very effective for this kind of thing.
The Hibernate tutorials provide a lot of examples for situations that are similar to the code you provided.
A highly recommended framework is JPersist, an extremely simple Database-to-POJO framework. No XML or annotations needed. I use it it my project because if I want a new table object, I simply create a bean.
The issue though in your situation is your wanting something to setup the database for you. Doing that would be very hard and your asking alot from a framework. With JPersist, you should be able to create a db table from class name and columns from fields, and then use phpMyAdmin's designer to resolve references.
5 min of reading the documentation for JPersist now will save hours in development time later.
JPA provides sufficient options to do this. For example you can use #Embeddable and #Embedded:
#Embeddable
class TypeB {
int id;
int someData;
}
class TypeA {
....
#Embedded
TypeB data1;
}
You can either manually create the underlying schema, or let something like hbm2ddl.auto=update to create it for you.