questions on ObjectBox data model rename - migration

Say I want to rename property "user" to "customer". I understand that I can add #Uid of "user" at the new property name. Like:
#Uid(123985252953064306)
String customer;
So I presume during the next build and run of my app, "user" in the database is renamed to "customer". My first questions are: can I then remove #Uid(123985252953064306) from my code for further builds? I guess the answer is yes if the app is only used by myself? So to maintain compatibility for endusers of the app, I still need to keep the #Uid annotation in the code. Is it correct?
My next question is: what if later I want to rename "customer" to "client"? Should I add an additional #Uid at the new property? Like:
#Uid(123985252953064306)
#Uid(124568645726267383)
String client;

The questions you are asking are covered by the docs in Data Model Updates and with some more background in Meta Model, IDs, and UIDs.
In short, once you put an #Uid on an property (or an entity) you can rename it anyway you want as often you want. ObjectBox takes the UID to identify the property and knows it been there before. Thus you need to keep it on the property.
So from
#Uid(123985252953064306)
String customer;
you can go to
#Uid(123985252953064306)
String someFancyName;
and back to
#Uid(123985252953064306)
String customer;
with keeping the same data for the property in the database.

Related

How to get original object after modifying with dojo.clone?

I have a object which returns from service say, studentInfo (which has id 1).
I have cloned as below:
this.studentsInformation=dojo.clone(studentInfo);
Now I try to update the cloned object - studentInfo
I have updated (say for id 1) and stored in database. If I create a new student info and try to update in a db, it has to go with id 2. But the object has id 1...
And also if I print this.studentsInformation, it is not showing the original object.. it has got modified object only..
So I want the original object after modifying and also I want to store the updated information after cloning as well. How can I achieve this?
why dont you store a reference in the clone to the original object ?
this.studentsInformation=dojo.clone(studentInfo);
this.studentsInformation.myMama=studentInfo;
Lucian

Need a concept on fetching data with HQL while three or more tables are in use

A small briefing on what I am trying to do.
I have three tables Content(contentId, body, timeofcreation), ContentAttachmentMap(contentId, attachmentId) and Attachment(attachmentId, resourceLocation).
The reason I adopted to create the mapping table because in future application the attachment can also be shared with different content.
Now I am using HQL to get data. My objectives is as follows:
Get All contents with/without Attachments
I have seen some examples in the internet like you can create an objective specific class (not POJO) and put the attribute name from the select statement within its constructor and the List of that Class object is returned.
For e.g. the HQL will be SELECT new com.mydomain.myclass(cont.id, cont.body) ..... and so on.
In my case I am looking for the following SELECT new com.mydomain.contentClass(cont.id, cont.body, List<Attachment>) FROM ...`. Yes, I want to have the resultList contain contentid, contentbody and List of its Attachments as a single result List item. If there are no attachments then it will return (cont.id, contentbody, null).
Is this possible? Also tell me how to write the SQL statements.
Thanks in advance.
I feel you are using Hibernate in a fundamentally wrong way. You should use Hibernate to view your domain entity, not to use it as exposing the underlying table.
You don't need to have that contentClass special value object for all these. Simply selecting the Content entity serves what you need.
I think it will be easier to have actual example.
In your application, you are not seeing it as "3 tables", you should see it as 2 entities, which is something look like:
#Entity
public class Content {
#Id
Long id;
#Column(...)
String content;
#ManyToMany
#JoinTable(name="ContentAttachmentMap")
List<Attachment> attachments;
}
#Entity
public class Attachment {
#Id
Long id;
#Column(...)
String resourceLocation
}
And, the result you are looking for is simply the result of HQL of something like
from Content where attachments IS EMPTY
I believe you can join fetch too in order to save DB access:
from Content c left join fetch c.attachments where c.attachments IS EMPTY

how to access column value after serialization activerecord

I have a simple model like this:
class User < ActiveRecord::Base
serialize :preferences
end
I want to access the raw value from mysql, not value before serialize. Is it possible?
I know I can use
ActiveRecord::Base.connection.execute("select * from users")
But I want to access from the User model.
Updated
Ok, this is what you are looking for:
User.find(params[:id]).attributes_before_type_cast["preferences"][:value]
This will return the string in its serialized form.
That is the closest you can get that I can find, it won't work if you have already gotten the object pulled from the database.
Sorry for misreading your question. You can use this from the User model too.
Leaving the old answer up just in case the other way of doing it is helpful to someone.
Old Answer
Just to be sure I understand the question, you want the raw data from the table. The data that rails serializes and puts in the database.
EX. You put in ['site_id','last_update','last_restart'] and you get "---\n- site_id\n- last_update\n- last_restart\n" and it is put in the database and saved. You want to retrieve this: "---\n- site_id\n- last_update\n- last_restart\n" from the database.
Ok, it took some fanagaling from the database but you can do it like so.
In a project I have a serialized array call devise_table_preferences that lists the preferences to display in a table in a particular order, like so:
user.devise_table_preferences = ['site_id','last_update','last_restart']
The serialized view of it is like so:
"---\n- site_id\n- last_update\n- last_restart\n"
Using your method above, I made a query like so:
preference = ActiveRecord::Base.connection.execute("SELECT devise_table_preferences FROM users WHERE id = #{#user.id}")
It returns an object in the console like so:
preference = #<Mysql2::Result:0x007fe4cdf34850>
Running:
preference.first[0]
Gave me this:
"---\n- site_id\n- last_restart\n"
I know its a big work around but it will definitely give you your data in its serialized way. Hope that it helps you out.
attributes_before_type_cast didn't work for me.
User.first.instance_variable_get(:#attributes)['preferences'].serialized_value
This works even if the object is loaded.
I think these days you want to say the following:
User.find(params[:id]).typecasted_attribute_value('preferences')

Use enum to select string from wicket properties file

I'd like to add a label to a wicket panel where the label's model is an enum value. Based on the value of that enum, I'd like to display a different message pulled from the page's properties file.
For example, here's an enum:
public enum ApprovalType { UNAPPROVED, APPROVED, BLOCKED };
I can easily add a label to the panel that has this enum as its model:
add(new Label("approval", new Model(ApprovalType.APPROVED)));
However, this will simply output UNAPPROVED, APPROVED, or BLOCKED. I'd like to output a localized message that is selected based on the value of this enum.
So if I have this properties file, what's the best way to get these messages to output?
UNAPPROVED=Your membership is currently pending approval
APPROVED=Your membership has been approved
BLOCKED=You have been blocked from membership
I can get it working like this:
add(new Label("approval", new ResourceModel(ApprovalType.APPROVED.name());
But the problem is that ResourceModel only accepts a string (resource key). I'd like to pull the value of the resource key automatically from a model (preferrably a CompoundPropertyModel). In other words, I don't want to do this:
Member member = (Member) getDefaultModelObject();
add(new Label("approval", new ResourceModel(member.getApproval().name())));
I'd rather do something like:
add(new EnumLabel("approval"); // assuming I have a CompoundPropertyModel
Is there a component that does this that comes with Wicket? Or do I need to write my own?
Lastly, I discovered this also works:
add(new Label("approval", new StringResourceModel(
"${}",
new PropertyModel<ApprovalType>(getDefaultModel(),"approval")
)));
But this seems overly verbose, and still doesn't utilize the simplicity of using CompoundPropertyModel.
Ideas?
Not sure if this 'll work, but maybe you could try writing your own EnumModel class that takes the value of an Enum and returns a ResourceModel value..
Please say so if the above isn't clear enough, I'll try to elaborate.

Persist a top-level collection?

NHibernate allows me to query a database and get an IList of objects in return. Suppose I get a list of a couple of dozen objects and modify a half-dozen or so. Does NHibernate have a way to persist changes to the collection, or do I have to persist each object as I change it?
Here's an example. Suppose I run the following code:
var hql = "from Project";
var query = session.CreateQuery(hql);
var myProjectList = query.List<Project>();
I will get back an IList that contains all projects. Now suppose I execute the following code:
var myNewProject = new Project("My New Project");
myProjectList .Add(myNewProject);
And let's say I do this several times, adding several new projects to the list. Now I'm ready to persist the changes to the collection.
I'd like to persist the changes by simply passing myProjectList to the current ISession for updating. But ISession.SaveOrUpdate() appears to take only individual objects, not collections like myProjectList. Is there a way that I can persist changes to myProjectList, or do I have to persist each new object as I create it? Thanks for your help.
David Veeneman
Foresight Systems
If you load objects like in your example - then yes you have to persist them one by one.
However, if you make a small design change, and load something like : Account that has an IList<Project> - if you specify cascade "what_cascade_you_need" in the mapping , then when you change the projects on Account , you only have to save Account and everything will get saved.