I've only just started out with CF9's ORM features, and have run into a problem.
I've got a single table set up - member - which has 2 records in it.
If I try:
<cfscript>
members = EntityLoad("member");
writedump(members);
</cfscript>
...I should get an array of member objects; but I get the error:
unexpected token: member near line 1, column 6 [from member]
The error occurred in \\vmware-host\Shared
Folders\Web\sites\testbed\webroot\orm\index.cfm: line 2
1 : <cfscript>
2 : members = EntityLoad("member");
3 : writedump(members);
4 : </cfscript>
If I try:
<cfscript>
members = EntityLoad("member", {});
writedump(members);
</cfscript>
...I get the expected array of 2 member objects - but it takes 5-10 seconds to return it.
But if I request a unique object:
<cfscript>
members = EntityLoad("member", 1, true);
writedump(members);
</cfscript>
...I get the result returned instantaneously.
Any ideas as to what the problem(s) is/are?
member.cfc:
component output="false" persistent="true"
{
// identifier
property name="memberid" fieldtype="id";
// properties
property name="firstname";
property name="lastname";
property name="address1";
property name="address2";
property name="city";
property name="postcode";
property name="country";
property name="email";
property name="telephone";
property name="uuid";
property name="password";
}
OK, I've figured it out...
It turns out that "member" is a (semi-)reserved word in Hibernate: https://forum.hibernate.org/viewtopic.php?f=1&t=1005886&start=0
Changing the object and table names to "sitemember" fixed the problem.
I would guess that it works fine if in the underlying HQL query there's a WHERE clause following the "SELECT FROM member"; but if you just have the basic entityload("member") then it doesn't have this WHERE clause.
I wonder if there are any other names I need to steer clear of?
Thanks for the help, Henry!
Related
I'm getting data from an SQL database.
var result: SQLResult = sqlStatement.getResult();
var resultsArray:Array;
if (result != null)
{
resultsArray = result.data;
trace(resultsArray.length);
}
When there's data in the database, the above code works fine. When there's not data, it errors out on the trace line...
Error #1009: Cannot access a property or method of a null object reference.
Why is that? Why is it making it through the conditional when result is null?
Thank you.
I have an Entity with a lot of fields.
<cfscript>
component persistent="true" output="false" {
...
property name="placeholder" default = 0;
property name="expired" update=false insert=false;
property name="admin" default = 0;
property name="partner" default = 0;
Much later, but in the same request. I am going to do this
if (!arguments.Account.getPlaceholder() ) local.arRoles.append("account");
if (!arguments.Account.getExpired() ) local.arRoles.append("event");
if (arguments.Account.getAdmin() ) local.arRoles.append("admin");
if (arguments.Account.getPartner() ) local.arRoles.append("partner");
And I get an error that looks like this
I do a dump of the object. It looks like it should be OK
Expired is not like the other fields. It is backed by a calculation done on the database. That is why it is
property name="expired" update=false insert=false;
Furthermore
Account = EntityLoadByPK("Accounts", arguments.id);
Many not have what is expected. A read from the DB must be forced
Account = EntityLoadByPK("Accounts", arguments.id);
EntityReload(Account);
When executing the following piece of code:
def xml = new XmlSlurper().parse(url)
title = rss.chanel.title
rss.channel.item.each {
sql.firstRow("SELECT COUNT(*) FROM news WHERE title = ? ", [it.title])
}
I get the following error:
Invalid argument value: java.io.NotSerializableException
What may cause it?
The problem was that it.title was a NodeChild object.
In order to get the serializable text of this object I had to use it.title.text(). It was quite tricky since I could use print it.title successfully
Understanding Magento Models by reference of SQL:
select * from user_devices where user_id = 1
select * from user_devices where device_id = 3
How could I perform the same using my magento models? getModel("module/userdevice")
Also, how can I find the number of rows for each query
Following questions have been answered in this thread.
How to perform a where clause ?
How to retrieve the size of the result set ?
How to retrieve the first item in the result set ?
How to paginate the result set ? (limit)
How to name the model ?
You are referring to Collections
Some references for you:
http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-5-magento-models-and-orm-basics
http://alanstorm.com/magento_collections
http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/using_collections_in_magento
lib/varien/data/collection/db.php and lib/varien/data/collection.php
So, assuming your module is set up correctly, you would use a collection to retrieve multiple objects of your model type.
Syntax for this is:
$yourCollection = Mage::getModel('module/userdevice')->getCollection()
Magento has provided some great features for developers to use with collections. So your example above is very simple to achieve:
$yourCollection = Mage::getModel('module/userdevice')->getCollection()
->addFieldToFilter('user_id', 1)
->addFieldToFilter('device_id', 3);
You can get the number of objects returned:
$yourCollection->count() or simply count($yourCollection)
EDIT
To answer the question posed in the comment: "what If I do not require a collection but rather just a particular object"
This depends if you still require both conditions in the original question to be satisfied or if you know the id of the object you wish to load.
If you know the id of the object then simply:
Mage::getModel('module/userdevice')->load($objectId);
but if you wish to still load based on the two attributes:
user_id = 1
device_id = 3
then you would still use a collection but simply return the first object (assuming that only one object could only ever satisfy both conditions).
For reuse, wrap this logic in a method and place in your model:
public function loadByUserDevice($userId, $deviceId)
{
$collection = $this->getResourceCollection()
->addFieldToFilter('user_id', $userId)
->addFieldToFilter('device_id', $deviceId)
->setCurPage(1)
->setPageSize(1)
;
foreach ($collection as $obj) {
return $obj;
}
return false;
}
You would call this as follows:
$userId = 1;
$deviceId = 3;
Mage::getModel('module/userdevice')->loadByUserDevice($userId, $deviceId);
NOTE:
You could shorten the loadByUserDevice to the following, though you would not get the benefit of the false return value should no object be found:
public function loadByUserDevice($userId, $deviceId)
{
$collection = $this->getResourceCollection()
->addFieldToFilter('user_id', $userId)
->addFieldToFilter('device_id', $deviceId)
;
return $collection->getFirstItem();
}
I want to retrieve list of roles for a logged in user.
Following is a code segment that reads user roles from the database.
ISession session = NHibernateHelper.GetCurrentSession();
var data = from s in session.Linq<ApplicationUserRole>()
where s.AppUser.ID = 1
select s.Role.Name;
List<Role> list = data.ToList();
AppUser: User entity
Role: Role entity.
As there are no data in the database for user id 1, it doesn't return anything.
Return type data is NHibernate.Linq.Query and it is not null.
It throws following error when I attempt to convert it to ToList();
"Index was out of range. Must be
non-negative and less than the size of
the collection. Parameter name: index"
How do I handle empty result sets?
This should work...
List<Role> list = data.Any() ? data.ToList() : new List<Role>();