db4o to preserve identity of objects - java

Is there a way to preserve an object identity in db4o.
Suppose I store a BigDecimal in embedded db4o.
When I read it twice I get two distinct objects with the same value (which is quite obvious).
Is there any setting to force db4o to cache query results so that two queries would return reference to the same instance, or do I have to do it myself ?

From my experience, running the same query twice on the same ObjectContainer should return the same (identical) objects each time.
You should not close and reopen the ObjectContainer between the queries, if you need the objects' identity.

Db4o does use IDs and UUIDs internally and you can access those if needed. Also worth reading is this.

you can make an id for each object of yours by using it's UUIDs, I mean add an attribute ID for the object and give it UUIDs value and store it, to update an object you can retrieve it by that Id and update it

Related

How to get the Object Reference having the hashcode or other Unique String in Java

this is my issue. Im storing Data into a database table which has a column where i store the hashcode (or can be some other Unique String such as an ID because the JVM can re-locate the objects, changing the hashcode). But once i get that String i want to access to the object mapped to that String. I can do it with HashMap like:
ConcurrentHashMap<String, MyClass> MyClassDictionary;
The average of objects to store would be like +800. I can take other options to avoid this kind of things but i really want to know if some of you know a better way than using HashMap.
I found something about a Referenceable Interface that i could implement, you can check it out in the next link:
http://docs.oracle.com/javase/jndi/tutorial/objects/storing/reference.html
Thanks for reading.
You can use any key in the HashMap which is Immutable. String by nature is immutable, which means the object cannot be changed, if someone tries to change the object, a new one will be created and the original remains as it is. So you are safe if you are using unique strings as key. The advantage of using immutable keys in any hashed collection is that, your key object will always be preserved or unchanged. And there will be no chance that someone by mistake and change the key, and leading to a problem that you lose the reference to the value. If the key is not immutable and it is changed from some other place in the code. Then you will never be able to fetch the associated value to that key. This is sometimes refer to as memory leak in java.
The hashCode of an object is very explicitly not unique; it is quite legal for your hashCode() method to just return 0 all the time. You will need to use some other identifier.
You look like you're crossing two separate issues here: Are your objects being stored in the database or just in memory? If they're only in memory, then there's no reason to put the identifier in the database, because the objects will get thrown away when the program restarts. If they're in the database, you need some sort of object-relational mapping solution to recreate Java objects from database rows, and you should look at JPA.

What is stored in memcached?

What is actually stored in memcached when used for DB query caching.
If your answer is query result, then how do i invalidate an entry in the memcached if an update is made on any entity that the query is dependent on?
what about join queries? Is it ok if i cache them? how will i know if a table in the join query is updated or not, so i can invalidate the cache entry.
Also pls suggest some examples or articles.
In memchached key/value pairs are stored in configured cache. When you store DB result set it storing java.lang.Object.
You can invalidate this value by using any memcached client methods. e.g. spymemcached client provides a method like replace(String key, int expression, Object ob) which says
Replace an object with the given value (transcoded with the default transcoder) iff there is already a value for the given key. You can also delete old object.

Converting Between Hibernate Collections and My Own Collections

I have set up Hibernate to give me a Set<Integer> which I convert internally to and from a Set<MyObjectType> (MyObjectType can be represented by a single integer). That is to say, When Hibernate calls my void setMyObjectTypeCollection(Set<Integer> theSet) method I iterate through all the elements in theSet and convert them to MyObjectType. When Hibernate calls my Set<MyObjectType> getMyObjectTypeCollection() I allocate a new HashSet and convert MyObjectTypes to Integers.
The problem is that every time I call commit, Hibernate deletes everything in the collection and then re-inserts it regardless of whether any element of the collection has changed or even that the collection itself has changed.
While I don't technically consider this a bug, I am afraid that deleting and inserting many rows very often will cause the database to perform unnecessarily slowly.
Is there a way to get Hibernate to recognize that even though I have allocated and returned a different instance of the collection, that the collection actually contains all the items it used to and that there is no need to delete and reinsert them all?
I think the best way to achieve your goal would be to use a UserType. Basically it lets you handle the conversion from SQL to your own objects (back and forth).
You can see an example on how to use it here.

JPA/Hibernate entityManager.persist(..) makes the entity's collection to become null even though they are saved

I have a PurchaseEntity that has a Set inside.
After doing entityManager.persist(purchaseEntity), purchaseEntity itself and purchaseItemEntity's are all saved to DB correctly.
But after that entityManager.persist(purchaseEntity) call, purchaseEntity.getItems() returns null.
Is this a normal behaviour of Hibernate provided entityManager.persist()?
Is there a way to keep the collection remain in the containing entity object after it's persisted?
No, that's not a normal behavior. Furthermore, this is most certainly not Hibernate's doing - it has to be something in your code. Can you post your source?

Persisting data suited for enums

Most projects have some sort of data that are essentially static between releases and well-suited for use as an enum, like statuses, transaction types, error codes, etc. For example's sake, I'll just use a common status enum:
public enum Status {
ACTIVE(10, "Active");
EXPIRED(11, "Expired");
/* other statuses... */
/* constructors, getters, etc. */
}
I'd like to know what others do in terms of persistence regarding data like these. I see a few options, each of which have some obvious advantages and disadvantages:
Persist the possible statuses in a status table and keep all of the possible status domain objects cached for use throughout the application
Only use an enum and don't persist the list of available statuses, creating a data consistency holy war between me and my DBA
Persist the statuses and maintain an enum in the code, but don't tie them together, creating duplicated data
My preference is the second option, although my DBA claims that our end users might want to access the raw data to generate reports, and not persisting the statuses would lead to an incomplete data model (counter-argument: this could be solved with documentation).
Is there a convention that most people use here? What are peoples' experiences with each and are there other alternatives?
Edit:
After thinking about it for a while, my real persistence struggle comes with handling the id values that are tied to the statuses in the database. These values would be inserted as default data when installing the application. At this point they'd have ids that are usable as foreign keys in other tables. I feel like my code needs to know about these ids so that I can easily retrieve the status objects and assign them to other objects. What do I do about this? I could add another field, like "code", to look stuff up by, or just look up statuses by name, which is icky.
We store enum values using some explicit string or character value in the database. Then to go from database value back to enum we write a static method on the enum class to iterate and find the right one.
If you expect a lot of enum values, you could create a static mapping HashMap<String,MyEnum> to translate quickly.
Don't store the actual enum name (i.e. "ACTIVE" in your example) because that's easily refactored by developers.
I'm using a blend of the three approaches you have documented...
Use the database as the authoritative source for the Enum values. Store the values in a 'code' table of some sort. Each time you build, generate a class file for the Enum to be included in your project.
This way, if the enum changes value in the database, your code will be properly invalidated and you will receive appropriate compile errors from your Continuous Integration server. You have a strongly typed binding to your enumerated values in the database, and you don't have to worry about manually syncing the values between code and the data.
Joshua Bloch gives an excellent explanation of enums and how to use them in his book "Effective Java, Second Edition" (p.147)
There you can find all sorts of tricks how to define your enums, persist them and how to quickly map them between the database and your code (p.154).
During a talk at the Jazoon 2007, Bloch gave the following reasons to use an extra attribute to map enums to DB fields and back: An enum is a constant but code isn't. To make sure that a developer editing the source can't accidentally break the DB mapping by reordering the enums or renaming then, you should add a specific attribute (like "dbName") to the enum and use that to map it.
Enums have an intrinsic id (which is used in the switch() statement) but this id changes when you change the order of elements (for example by sorting them or by adding elements in the middle).
So the best solution is to add a toDB() and fromDB() method and an additional field. I suggest to use short, readable strings for this new field, so you can decode a database dump without having to look up the enums.
While I am not familiar with the idea of "attributes" in Java (and I don't know what language you're using), I've generally used the idea of a code table (or domain specific tables) and I've attributed my enum values with more specific data, such as human readable strings (for instance, if my enum value is NewStudent, I would attribute it with "New Student" as a display value). I then use Reflection to examine the data in the database and insert or update records in order to bring them in line with my code, using the actual enum value as the key ID.
What I used in several occations is to define the enum in the code and a storage representation in the persistence layer (DB, file, etc.) and then have conversion methods to map them to each other. These conversion methods need only be used when reading from or writing to the persistent store and the application can use the type safe enums everywhere. In the conversion methods I used switch statements to do the mapping. This allows also to throw an exception if a new or unknown state is to be converted (usually because either the app or the data is newer than the other and new or additional states had been declared).
If there's at least a minor chance that list of values will need to be updated than it's 1. Otherwise, it's 3.
Well we don't have a DBA to answer to, so our preference is for option 2).
We simply save the Enum value into the database, and when we are loading data out of the database and into our Domain Objects, we just cast the integer value to the enum type.
This avoids any of the synchronisation headaches with options 1) and 3). The list is defined once - in the code.
However, we have a policy that nobody else accesses the database directly; they must come through our web services to access any data. So this is why it works well for us.
In your database, the primary key of this "domain" table does't have to be a number. Just use a varchar pk and a description column (for the purposes your dba is concerned). If you need to guarantee the ordering of your values without relying on the alphabetical sor, just add a numeric column named "order or "sequence".
In your code, create a static class with constants whose name (camel-cased or not) maps to the description and value maps to the pk. If you need more than this, create a class with the necessary structure and comparison operators and use instances of it as the value of the constants.
If you do this too much, build a script to generate the instatiation / declaration code.

Categories