I am just starting to apply RealmDB in my application. I have one question regarding nesting objects.
I have previous experience working with Entity Framework. There is one useful feature available in Entity Framework - mappings.
The problem is that I need to have nested object. Here is an example
public class SessionModel extends RealmObject {
private UserModel userModel;
private ExpirationDate expirationDate;
}
As you can see the members are not simple types, but classes instead. Therefore it is problematic to map them correctly.
I wonder if there is any way to use custom retriever or mapper to get collect all objects manually and return a model with all fields set.
Thank you
Related
I want to ask you about model and ModelWrapper behavior. According to Wikipedia article about model component of MVVM:
Model refers either to a domain model, which represents real state
content (an object-oriented approach), or to the data access layer,
which represents content (a data-centric approach).
I was looking for ModelWrapper usage samples in mvvmFX documentation and examples, but I found only data access layer model sample. I need to use model classes with business logic. For example, changing class state in setter method (is the side effect usage a code smell here?):
public class ModelClass {
private int intField;
private String stringField;
public int getIntField() {
return intField;
}
public void setIntField(int intField) {
if (intField == 100) {
this.stringField = "";
}
this.intField = intField;
}
public String getStringField() {
return familyName;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
}
According to ModelWrapper documentation:
The user changes the values of the viewModel properties (via the UI). The state of the underlying model instance may not be changed at this point in time! When the user clicks an Apply button (and validation is successful) copy all values from the ViewModel fields into the model instance.
How to use such model classes, and not to implement the business logic twice (in the model class at the first time and in the ViewModel class at the second time)? Or maybe I have to move business-logic in other place?
The ModelWrapper is mainly intended for Java Bean classes without much logic. It's a helper to prevent users from having to write code to copy values from a model object to the ViewModel and back.
In you example when you invoke the commit method of the ModelWrapper it will copy all values from the viewModel properties to the model instance by invoking all registered setter methods. This is done in the order in which the property fields are registered. If you have registered the intField-Property first, the ModelWrapper will first invoke the setIntField method (which changes intField and stringField in the model instance) and then invoke the setStringField method which overwrites the stringField.
However, having to modify the order of field registration doesn't sound like a good idea and will most likely not scale for more complex model classes.
So in the end I think the ModelWrapper is not a good tool for your use-case. In many cases there is no general answer on how to connect the model classes with the viewModel. It highly depends on the intended behavior and the use-cases.
Regarding the question on the side-effect in the setter and if this is a code-smell: In my oppinion it's perfectly fine to modify the state of multiple internal fields with a single method. This is what OOP and information-hiding is all about. However, in Java there is the convention of getter and setter methods. If you name a method setIntField most Java developers will assume that this method only modifies intField and nothing more. So I would recommend to find a better name for such a method and keep getters and setters simple and straight forward.
Using Hibernate with MySQL, I like to use same class and store in two different table. How can i map one class with multiple tables?
I came across this thread,
hibernate two tables per one entity
which gives a suggestion to use two different Identity Name for same class through XML configuration. Can some one give me pointers how should i do this mapping in Java configuration? Or can it be done using annotation?
example,
There is Student Class
#Entity
#Table(name="Student_1")
public class Student{
#Id
private int StudentId;
private int StudentName;
private int studentMailId;
}
I like to have similar Table with same fields with the table name as Student_2. How should I annotate and use it to save in different tables?
I know this question was asked long time ago, and a response was posted here .
I would like to suggest an alternative way, without using any of hibernate things.
Declare an interface with getter and setter methods of commun columns, then make your Student_1 class and Student_2 classs implement this interface.
Leave your JPA mapping in this two class as usual, then in your code, you can invoke method of this interface instead.
I am creating an application and at the front I check if the user is an admin, user, moderator or superadmin. Based on this I create a different XML.
So what I currently do is to pass a string in the method argument that converts the object to XML to specify which mapping it should use. However passing those strings around isn't good. Are there any patterns to do this better?
I could bring the role check to the mapping class, and then change the mapping id to the same as the role of the current user. But I don't think security checks fits those classes.
Would you just create an enum to keep the roles and pass that instead of a string?
Or create different classes and use a factory to return the right object?
A Common Interface Approach
By implementing a common interface between all return objects, you can develop some loose coupling in your code. For example:
public interface XmlReturn
{
public void displayXML(); // Just an example method.
}
And a class that implements this interface:
public class AdminXmlReturn implements XmlReturn
{
public void displayXML() { // Some code here for the admin XML }
}
With this, you can generate some sort of factory that takes a discriminator:
public abstract class XmlFactory
{
public static XmlReturn getInstance(String type)
{
// Using string as an example type. Doesn't need to be.
if(type.equals("Admin")) {
return new AdminXmlReturn();
}
}
}
and by referring to the object by it's interface type, you can generate as many different XML files you want, without having to change any code. IE:
public void loadPage(String permission)
{
// permission can be any type. This is just an example.
XmlReturn xml = XmlFactory.getInstance(permission);
xml.displayXML();
// This method exists in all objects that implement XmlReturn
}
Advantages
This approach has the main advantage that you can add as many new XML files and permissions as you want, and you won't need to change the code that loads the XML. This "separation of concerns" will help you to make your program very manageable and extendable.
By porting your decision logic to a factory, you help make your code more readable, and allows other people to abstract away from the details of the inner workings of your program, if you intend on sharing your code.
You question is not very clear. Anyway, I try to give some option:
if you want to serialize to XML different kind of users, then I would suggest to model the different kind of users as a hierarchy of classes, and have a specialized toXML() serialization method in each class. By the way, JAXB can help you a lot, if this is what you want to do.
if you have a class XMLBuilder that writes some XML, and the way the XML is built depends on the kind of user, then I would suggest to model your different kind of users with a hierarchy of classes, and then use method overloading in XMLBuilder, i.e. have several build() methods each one taking as input a different subclass of your user-kind hierarchy.
I hope this helps.
I'm making my first Java project, and trying to learn OO programming as well as MVC.
Say that you have a class "Products" and a number of objects of that class. Your GUI want to display a list of these objects, possibly also with some filter etc. I can think of several ways to do this:
The GUI could simply read all objects and list them.
Make a globally available method that returns all the objects. This could be placed in some kind of repository for global functions.
Make a static method inside the Products class that returns a list of all objects.
What is the proper way to do this, and where would you put the code?
As you want to learn MVC, you already know that in order to implement MVC pattern you need three layers: Model, View, Controller. In your case, you have the two of the layers, Model (Product) and View (ProductGUI, assuming this is a different class). What you are missing is the Controller.
In order to leverage from MVC, I suggest you to implement the Controller layer with an API approach so that you have an interface, ProductController; and a class implementing the interface, ProductControllerImpl. This interface-class separation lets you to switch between alternative implementations and also allows Mocking your services for user interface testing (See Wikipedia for further explanations).
Let me also try to explain this with a simple example.
Assume you create the interface for your Controller layer as such:
public interface ProductController {
public List<Product> listProducts();
public List<Product> listProducts(NameFilter nameFilter);
}
Then you can create a Mock implementation for this interface for testing purposes as such:
public class ProductControllerImplMock implements ProductController {
List<Product> products;
public ProductControllerImplMock() {
products = new ArrayList<Product>();
}
public List<Product> listProducts() {
products.add(new Product("A"));
products.add(new Product("B"));
return products;
}
public List<Product> listProducts(NameFilter nameFilter) {
products.add(new Product("A"));
return products;
}
}
Note: Assumining you have a NameFilter class that aims at filtering Product's by name.
If you decide to use a database to store your products, then you can implement ProductControllerDatabaseImpl which will query your database and retrieve entities for listing and which will most probably introduce WHERE clause to the query for listProducts(NameFilter) method.
Actually, things are never this simple. What is shown in this example will be referred to as DAO (Data Access Object) in more complex applications and there will be a separate layer, generally called Business layer instead of Controller layer, which will implement the actual logic for the application. But I tried to keep the example as simple as possible for simplicity.
IMHO, the OOP approach would be to expose the collection via a basic accessor method in the Products class. If you're concerned about the collection being modified, either wrap the collection with one of the unmodifiable collections made available by the Collections class, or return a copy.
Edit -
And concerning the GUI, be aware of concurrency-related issues.
Example -
final class Products
{
private final List<Foo> listOfFoo;
Products(List<Foo> listOfFoo)
{
this.listOfFoo = listOfFoo;
}
public List<Foo> getListOfFoo()
{
if(listOfFoo.isEmpty())
{
return Collections.emptyList();
}
return Collections.unmodifiableList(listOfFoo);
}
}
I'm borrowing the "slice" meaning from C++.
Let's say I hava a simple POJO that's persisted via Hibernate:
class Person {
private long id;
private String name;
...
// getters and setters here
...
}
Now, when I retrieve an object from the database I know it was "instrumented" by Hibernate (its real class is a Person-derived generated automatically). I want to convert it back to a "plain" person object. Tnat would be used, for instance, to submit the object to XStream and have the result containing only what Person contains.
I could do it by defining a copy constructor, but I don't want to have the hassle of having to write copy constructors for every ORM class (not to mention the violation of DRY principle).
So I was wondering if
a) is there already a Java lib that does it?
b) If not, would it be practical to write one using reflection?
In case of (b), any recomendations/guidelines/code skeletons would be appreciated.
The bean mapping library Dozer does an excellent job of this and is dead simple to use.
Simply map an instance of the bean returned by Hibernate to it's own class:
Person person = session.load(...);
BeanMapper mapper = ...;
Person cleanPerson = mapper.map(person, Person.class);
voila, no more Hibernate proxies or lazy-loaded collections!
The class org.apache.commons.beanutils.BeanUtilsBean probably does almost everything you want. The copyProperties method will go through calling the getters on your Entity and looking for setters with a matching property name on a target object you provide. You may need to handle some nested entities, depending on what kind of behavior you want and if/how you map relationships.
If you need to get more sophisticated you can register a Converter for turning your nested entity types into something else as well.
There is an interesting discussion about your problem here
http://www.mojavelinux.com/blog/archives/2006/06/hibernate_get_out_of_my_pojo/
Several solutions are proposed in the comments. In particular
http://code.google.com/p/entity-pruner/
http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/
I personally am huge on layer separation, and would argue that classes that you want to serialize across the wire or to XML should actually be separate from your data access layer classes, which would also solve the problem.
class SerializablePerson
{
... fields you care about ...
SerializablePerson(Person person)
{
... set only what you care about ...
}
}
You could have a Person class without persistence information wrapped by a persistent counterpart, like this:
public class Person implements Serializable
{
private String name;
// others.
}
public class PersistentPerson
{
private Long id;
private Person data; //
public Person getPerson() { return this.data; }
}
I'm not sure the design is worth it. The dual model makes me throw up in my mouth a little, just while writing this example.
The larger question is: Why do you think this is necessary? IF there's no good way to tell XStream to not include the id when serializing, I'd say it'd be better to write your own javax.xml.bind.Marshaller and javax.xml.bind.Unmarshaller to get what you want.
There are better ways to solve this problem than bastardizing your entire design.