I have a question on object ID of an object across JVMs. ie Say suppose i have persisted an object created on JVM1, and now I want to use the same object on JVM2.
So how to do that.
Will the object Id of the object same on both the JVM?
If yes for the above question, then what will be the case if the JVM2 has already an object with the objectID same as the one which is persisted.
thanks.
The object won't exist on JVM2 until you deserialize it. There's no concept of a "universal object ID" in Java - if you need an ID for your objects, you'll have to add it yourself. You could add a UUID field to your object; you'd then want to maintain some sort of cache to allow you to spot duplicates.
Are you really sure you need all of this? It may be worth taking another look at the bigger picture and redesigning.
Check out serialization here or alternatively you could use RMI - check out this link
I'm not really sure what you mean by Object Id, if you mean the reference you get printed out when you print out an object with no toString method then, this is not an object ID this is the memory address reference and will be different on each JVM and different on different invocations of the same program.
You could add a UUID to your object to create an unique id.
UUID javadoc
UUID uuid = UUID.randomUUID();
Related
As shown below:
c1 Class<T> (com.horstmann.corejava.Employee) (id=22)
I am curious about what does this id exactly mean? Can I actually modify it? And I want to know something related.
That is an opaque internal (to the JVM) identifier that is unique for each object. You can think of as a "handle" for the instance.
You cannot change it, and it can be different for a given object instance every time you run your code.
It can be useful when you are stepping through your code in the debugger and have many instances of a class. You can look at two instances and determine if they are actually the same instance accessed through different references.
Think of it this way. Say, you have multiple instances of this class. In cases of debugging, this id can be a unique identifier.
The id is arbitrarily assigned by the eclipse debugger. My best guess would be that eclipse has some sort of an a map, something like IdentityHashMap<Object, Integer>, assigning a unique integer to every object.
We are using an OODBMS, which allows both Java "entities" and serialized objects too. The DB supports true graphs (no "tree" restriction) and serialized objects can safely reference entities as well. The DB works (almost) transparently, and we can do whatever we want, and it-just-works.
Now, I've discovered that objects that had been marked as "logically deleted" (using a simple boolean flag, rather then built-in DB functionality, since the DB doesn't have such a concept) are loaded/saved within a particular object graph.
I want to know which object(s) references those "zombie" objects. Trying to use reflection to iterate over the graph has not worked so far. Instead of the DB, I can simply use Java serialization to export the object graph, and this also causes the "zombie" objects to be serialized.
My question is: can I somehow extract the information about the object(s) that is holding a reference to a "zombie" object during the serialisation process (the "parent" object)? There can be more then one, but as long as I have one, I can work iteratively until I killed off all those invalid references.
Most OODBMS allow to run queries which return object references that satisfy certain constraints. So you could write something like this:
return all objects
where deleted == true
and Foo.bar == this
where Foo is the type of the object which references the deleted objects and bar is the field/property that contains the reference.
The exact syntax depends on your OODBMS.
I am designing the service layer of my web application. There are some scenario which I need to get the Orders based on the Product.
When I design the API, should I pass by object or value?
Order order = new Order();
String orderId = "1";
order.setId(orderId);
List<Product> products = getProductByOrder(order);
List<Product> products = getProductsByOrderId(orderId)
Well, i think you are making some mistakes with this concepts, in this two ways you are making references to this objects, order and orderId(since String is an object too.)
But the best approach in this case is using getProductsByOrderId(orderId) because your code will be loosely coupled, since your other layer won't have to know about an Order object, and just know about a string object. If we can pass simpler objects as parameters, we do.
Good example from #Pienterekaak posted as comment:
"In many cases its easier to obtain just an orderid, then a whole order object. (for example, you would include an order id in a REST call, not the whole order object)"
From my experience i would go for:
List<Product> products = getProductsByOrderId(orderId)
With the argument, that for the first call, you need an Order object, and for the second call you just need an id, which is probally easier to obtain.
Actually both of these are passing by value. Java only passes by value. In both of these cases you are passing a reference to an Object (String) or (Order). You are passing as a value the location of memory where this object is (pointer). If you are passing a primitive type like int it passes the value like 1 but if you are passing an object it passes the value of the pointer to the object ie. memory location. In any case you are always passing by value.
If you have a Map storing the Order objects it is actually more efficient to pass the Object itself because you are directly passing the pointer for that object. If you pass the String id of 1 you are passing a pointer to that string then you would have to use that string to look up your Order object which is actually adding more processing then just passing a pointer to the object directly.
OrderId belongs to the concept of an order. If you pass the order id, the product has to know, how an order is identified. That's not loosely coupled.
If you put the method into Order, so you can call a property like
List order.Products
only the Order concept knows, how products and orders are connected, which sounds right to me.
Products shouldn't know anything about orders but orders should know about products.
If you use Hibernate, you could configure it to do it for you with an one-to-many, since orderId is a primary key in your order table.
I'm just learning Java but I keep running into the same problem over and over again
How do i revert to an old state of some object efficiently?
public class Example {
MyObject myLargeObject;
public void someMethod(){
MyObject myLargeMyObjectRecovery = myLargeObject;
/**
* Update and change myLargeObject
*/
if(someCondition){
//revert to previous state of myLargeObject
myLargeObject = myLargeMyObjectRecovery;
}
}
}
The above is how I would like the code to work but it obviously doesn't since myLargeObject and myLargeObjectRecovery are references to the same object.
One solution is to create a copy constructor. This is fine for small objects but if I have a large object (in my project the object is a large 2D array meaning I would have to iterate over all of the entries), this way feels wrong.
This must be a very common problem in Java, how do others get around it?
Either deep copy, as you noted, or possibly serialization. You could store a serialized string, and then reconstruct the object from it later.
The best solution depends on whether you have external references to your MyObject instance or not.
If you use the myLargeObject from the Example class only, you can use
Serialize your object at the savepoint, and deserialize at the restore point (the serialized byte[] must be transient)
Create a new instance with a Copy Constructor (doing deep copying) at the savepoint, and replace the reference at the restore point.
If you have access to the MyObject instance from outside, then it becomes a bit more interesting, you must introduce synchronization.
All of your methods on MyObject must be synchronized (to avoid inconsistent read)
You should have a synchronized void saveState() method which saves your state (either by serialization, or by copy constructor) (the latter is better)
You should have a synchronized void restoreState(), where you internally restore your state (for copying fields you can use a common code fragment with the copy constructor)
In all cases it is recommended to close the transaction (kind of commit()) at some point, it means that when you get there, you can delete the saved state.
Also, it is very important, that if you have an underlying data structure, you should traverse the whole structure for it. Otherwise you may experience problems with the object references.
Be careful with JPA Entities or any externally-managed objects, it is unlikely that any of these methods will work with them.
If you assign a object to another, jvm refers to same object in the memory. Therefore, the changes on the object will be in the other objetc which references.
MyObject myLargeMyObjectRecovery = myLargeObject;
It is the same in your code. myLargeMyObjectRecovery and myLargeObject refer to same object in the memory.
If you want to exact copy of any object you can use Object.clone() method. this method will copy the object and return a object which is refer to another object whose fields and their valus same as the coppied object.
Since clone method is protected you can not access it direcly. you can implement a Prototype pattern depending on your requirements.
http://www.avajava.com/tutorials/lessons/prototype-pattern.html
public class MyObject{
//fields, getters, setters and other methods.
public MyObject doClone()
{
MyObject clonedObject = this.clone(); //you may need to override clone()depending on your requirements.
return clonedObject;
}
}
and call it in your code
MyObject myLargeMyObjectRecovery = myLargeObject.doClone();
The Memento Pattern addresses the design issue of the revert to previous state problem. This approach is useful when you need to capture one or multiple states of the object and be able to revert to them. Think of it as an N-step undo operation, just like in a text editor.
In the pattern you have a stateful object Originator, which is responsible for saving and restoring snapshots of it's state. The sate itself is saved in a wrapper class called Memento, which are stored in and accessed via the CareTaker.
In this approach the easiest idea is to deep-copy your objects. However this may be inefficient regarding performance and space, since you store whole objects and not the change-sets only.
Some object persistence libraries provide implementations of transactions and snapshots. Take a look at Prevayler, which is an object persistence library for java and an implementation of the prevalent system pattern. The library captures the changes to your objects in form of transactions and stores them in-memory. If you need a persistent storage of your POJOs, you can save snapshots of your objects on disk periodically and revert to them if needed.
You can find more on serializing POJOs in this SO question: Is there a object-change-tracking/versioning Java API out there?
I am developing a java application which needs a special component for dynamic attributes. The arguments are serialized (using JSON) and stored in a database and then deserialized at runtime. All attributes are displayed in a JTable with 3 columns (attribute name, attribute type and attribute value) and stored in a hashmap.
I have currently two problems to solve:
The hashmap can also store objects and the objects can be set to null. And if set to null i dont know which class they belong to. How could i store objects even if they are null and known which class they belong to? Do i need to wrap each object in a class that will holds the class of the stored object?
The objects are deserialized from json at runtime. The problem with this is that there are many different types of objects and i don't actually know all object types that will be stored in the hashmap. So i am looking for a way to dynamicly deserialize objects.. Is there such a way? Would i have to store the class of the object in the serialized json string?
Thanks!
Take a look to the Null Object Pattern. You can use an extra class to represent a Null instance of your type and still could contain information about itself.
There is something called a Class Token, Which is the use of Class objects as keys for heterogeneous containers. Take a look to Effective Java By Joshua Bloch, Item 29. I'm not sure how this approach could work for you since you may have many instances of the same type but I leave it as a reference.
First of all, can you motivate why you use JSON serialization for your attributes ?
This method is disadvantageous in many ways in my opinion, it can cause problems with database search and indexing, make database viewing painful and caus unnecessary code in your application. These problems can be not an issue, it depends how you want to use your attributes.
My solution for situation like these is simple table containing columns like:
id - int
attribute_name - varchar
And then add columns for each supported data type:
string_value - varchar
integer_value - int
date_value - date
... and any other types you want.
This design allow for supreme performance using simple and typesafe ORM mapping without any serialization or other boilerplate. It can store values of any type, you just set correct column for attribute type, leaving all other with null. You can simulate null value by using null in all data columns. Indexing and searching also becomes a piece of cake.