getPropertyNames() not showing Identifiers and How To call Functions inside ORM Object

Hi All,
Using ORM and VirtualEntityService, I was trying to use the getPropertyNames() function to get a list of all the properties in my ORM Object. But only got properties that were not Identifiers. After Googling I found out that in Hibernate we need to use the getIdentifierType() and getIdentifierPropertyName() to get Identifier properties.

Since I do not see them in the VirtualEntityService, is there a way to get all properties of an ORM Object?

Another question, if using VirtualEntityService, how am I able to call functions I declared in my ORM Object? I tried to try what was suggested by Dan Vega
and created a public function to get Property Values but I do not know how to call the function if on VirtualEntityService. So I got curious in case I need to access a function of an ORM Object in the future.

Thanks
Julian

– using ColdBox 3.8

is there a way to get all properties of an ORM Object?

you’ll have to write a function that will iterate through all properties and return a memento. ive written this method if youre interested.

then you could use this method in conjunction with a method to dynamically find a property based on a name.

Thanks Aaron, Could you share your function?
What I currently do is add this into my Data Service.

`

var properties = evaluate(‘GetMetaData(new #rc.reqFunction#()).PROPERTIES’);
var propertyList = ‘’;

for(i=1; i <= arrayLen(properties); i++){
propertyList = listAppend(propertyList,properties[i].name);
}

`

I just does not feel right to call the ORM Object directly without using the ColdBox Entity Service but I really need to have the properties list for my Application.

I also wish they I could call any of the functions I have in the ORM Object through ColdBox’s Virtual Entity Service, but I still do not know how to do this.

Thanks
Julian

ORM Entities, already have all the properties for the DB, could you explain what scenario you want all properties like that.

Sure Andrew, the scenario is like this.

There are 2 scenarios that I would appreciate your help on:

Scenario 1 - When I need all Properties:
I am creating an API which does CRUD for the place I am working at.
For List calls the API Call will contain 2 additional parameters if needed for Search and for Sort, like this

`
searchParams:[
{
“property”:“user_role”,
“method”:“eq”,
“value”:“R01”
},
{
“property”:“meal_role”,
“method”:“eq”,
“value”:“SU”
}
]
sortParams:[
{
“property”:“user_role”,
“method”:“desc”
},
{
“property”:“user_name”,
“method”:“asc”
}
]

`

What I need is to search if the property is indeed part of the ORM Object and then I will do search or sort using the requested method (naturally there is authentication and checking if the method is valid).
The code for Sorting would be like this:

`

if (isDefined(“rc.sortParams”)) {
for (sortParam in DeserializeJSON(rc.sortParams)) {
if (ListFindNoCase(propertyList, sortParam.property)) {
var getMe = listGetAt(propertyList, ListFindNoCase(propertyList, sortParam.property));
c.order(getMe, sortParam.method);
} else {
returnMe.returnMessage = returnMe.returnMessage & ‘Error Search: #sortParam.property# not found in #rc.reqFunction#|’;
}
}
};

`

The problem I have is when I try to use getPropertyNames to get the propertyList

`
var propertyList= TableService.getPropertyNames(“ORMObject”);

`

then properties that are Keys will not be returned. So I will not be able to validate and therefor not be able to do search or Sort for Key Properties.

Scenario 2 - Calling Function of an ORM Entity:
I was looking at Dan Vega’s Blog for a Solution and inside he suggested putting Functions inside the Object, like this:

`

component accessors="true" {
	property userid;
	property firstname;
	property lastname;
	/**
	 * @hint this method will return an array of key/pair values for
	 *       each property in our component dynamically.
	 */
	public array function getPropertyValues(){
		// the properties of our component
		var properties = getMetaData(this).properties;
		// the return array
		var propertyValues = [];
		for(i=1; i <= arrayLen(properties); i++){
			var property = {};
			property.key = properties[i].name;
			property.value = getPropertyValue(property.key);
			arrayAppend(propertyValues,property);
		}
		return propertyValues;
	}
	private any function getPropertyValue(String key){
		var method = this["get#key#"];
		return method();
	}
}

`

Which got me wondering, if it is possible to call an object of an ORM Entity. For example:

`
var TableService = new VirtualEntityService(entityName=user);

writeDump(TableService.getPropertyValues());

`

But this was not working. Am I missing something here?

Thanks
Julian

ORM Entities are mapped Database tables and fields, therefore any searching you need to do would be done across the database. I am still not understanding how you are trying to link an Entity and search across its fields. The fields will alwasy contain the same data so a standard if condition would work.

I think if you want to do a search across the tables, then you should be looking into ORM Search which Adobe included in the Enterprise edition.

What are you trying to achieve here, because I am lost. If you have an array of Entities, this will not work because you would be loading up all the data to do the search and if you have millions of records this will kill your memory fast.

Any search on the DB should be done with the right tools.

Hi Andrew,
Thanks for bringing up Adobe ORM Search, I will certainly look into it and hopefully be able to replace my search and sort function with it.

But I would like to get back to the first question.
I am still curious how to get all property names of an ORM Entity. Like I said, i tried using getPropertyNames() but any properties that are marked as ID (fieldtype=“id”) are not showing up. Am I missing something here?

To do that you need to look deeper into Hibernate and utilize the classes.

This is how you do it in Java and Hibernate, so it may help with CF-ORM

Class<?> currentClass = User.class;
for(String field: "[group.name](http://group.name)".split("\\Q.\\E")) {
    currentClass = sessionFactory.getClassMetadata(currentClass).getPropertyType(field);
}

Still curios what searchable things, are in an ORM that you would need to search for? That screams bad news to me…

Why you don’t build the criteria and get what you need in one hit first is beyond me. But more importantly why there would be anything else searchable that is not persisted to the DB!!

I have no idea what problem you’re trying to solve there, but it sounds over complicated to me.

Is there a reason you can’t use the getKey() from the base ORM service to get the primary key?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Hi Brad,
That is working perfectly!

I googled and got getIdentifierType() and getIdentifierPropertyName() to use in Hibernate, which were not working.

Thanks
Julian

I think I haven’t been clear with my scenario, let me try again to explain what I am trying to do here.

So, I have this API that is accessed from a Client (Web Application, Mobile Apps, extJS Apps, etc.)
Lets assume the Client is asking for a resource, as an example a List of Books based on a search criteria.

So in the API Call, I am asking them to put the Criteria into a parameter (can be URL, Form, etc., this should not matter as I am using RC to get this) that is JSON serialized. Like this:

`
{
“searchParams”:[
{
“property”:“bookName”,
“method”:“eq”,
“value”:“DO”
},
{
“property”:“bookAuthor”,
“method”:“eq”,
“value”:“DO”
}
]
}

`

And then I am building the Criteria based on the searchParams. This is easy with the Criteria Builder:

for (searchParam in DeserializeJSON(rc.searchParams)) { criteria.eq(searchParam.property,searchParam.value); }

  • In the full code I am looking if the method is correct (eq, lt, gt, etc) and build the Criteria based on that

The problem happens if the property is not in the ORM Entity. For example, if they try to search for BookNumber which is not part of the Table then it would throw an error.
I was looking at 2 options:

  1. Create a CFTry & CFCatch for catching all the errors

  2. Looking at the properties of the ORM Object and look if the property is actually part of it
    In order to try out option number 2, I had to somehow get all the properties of the ORM Entity including all the Keys.

Thanks

Julian

Sounds like you’re allowing for the user to enter anything in the search and return matched results, no matter what table the data exists in.

If that is the case, I think you might want to look into ORM Search then. Because you have to load the entity before you can even inspect it, which is a performance issue right there (depending on usage).

Andrew,
Well, I am adding Authorization into it to make sure they are not able to see everything but I will definitely look into ORM Search now.

Thanks
Julian

sorry. misread your post.