Ignored default value in Lucee Orm - orm

I set my persistent component with this property:
<cfproperty name="active" ormType="timestamp" notnull="true" dbDefault="now()" />
Now, if I save an entity by not specifying its created_at value, I get an error: not-null property references a null or transient value: User.active.
How can I skip specifying all the columns when creating entities?
Thanks!

Rather than setting defaults in the database schema, I would define them in your entity's properties using the default attribute to avoid null values.
However, bear in mind that only simple and non-dynamic values - such as fixed strings and numbers - can be defined as defaults. If you need to define a complex value, like an array, or a dynamic one, such as Now(), you'll need to set those in the entity's init() method.
component name="user" accessors=true persistent=true{
property name="active" ormtype="boolean" default=false;
property name="created_at" ormtype="timestamp";
function init(){
variables.created_at=Now();
return this;
}
}

Related

Exclude property from INSERT command in nhibernate

I have an entity with a property which I wish to be readonly - meaning that when I insert this entity to the DB, SqlServer will generate the property's value automatically so I need nhibernate to ignore this property when executing the INSERT command but retrieve it when selecting the entity.
Important note: this property isn't ID! I don't want NHibernate to initialize it using generator, SqlServer will do it by itself.
And another note: I use configuration mapping so no fluent mapping solutions please.
That functionality is supported. There are two attributes:
<property name="GeneratedBySql" insert="false" update="false" />
The same could be applied even for reference mapping
<many-to-one name="ReferenceGeneratedBySql" insert="false" update="false" />
If we want to use Mapping-by-Code we do have the same in places, see:
Mapping-by-Code - Property (by Adam Bar)
Snippet cited:
Property(x => x.Property, m =>
{
m.Column("columnName");
...
m.Update(false);
m.Insert(false);

How to save through parent table on one-to-one relationship over primary key

I am trying to saveentity with first table where tables linked with one-to-one relationship on primary key. Here is code that I am trying,
tbl6.cfc
component name="tbl6" persistent='true' accessors="true"{
property name="id" fieldtype="id" generator="native";
property name="col";
property name="tbl7" fieldtype="one-to-one" cfc="tbl7";
}
tbl7.cfc
component name="tbl7" persistent='true' accessors="true"{
property name="tbl7id" fieldtype="id" generator="foreign" params="{property='tbl6'}";
property name="tbl6" fieldtype="one-to-one" cfc="tbl6" constrained="true";
property name="col";
}
index.cfm
<cfscript>
ormreload();
objt6 = entityNew("tbl6",{"col":"tbl6"});
objt7 = entityNew("tbl7",{"col":"tbl7"});
objt6.settbl7(objt7);
objt7.settbl6(objt6);
entitysave(objt6);
</cfscript>
In above case ORM only save record for tbl6, but if I change entitysave argument to objt7 it store record for both table. I am not sure what I am doing wrong here. I am trying this in RAILO 4.1
Please help.
Ah, I got that, I just need to add cascade="all" in property of tbl7 in tbl6.cfc
property name="tbl7" fieldtype="one-to-one" cfc="tbl7" cascade="all";
I just keep question to help others.

Could not find the property - exception after switching from NHibernate 3 to 3.3.1

I have a class with a field:
protected DateTime insertDate;
This is mapping for this fiels:
<property name="InsertDate" access="field.camelcase" update="false" />
This field is set when with ctor
public DocuBase(DateTime insertDate)
and is persisted only when row is added to the database. I don't need property for it at all, no setter & no getter. I worked in NHibernate 3.
And now, I've moved from NHiberbate 3 to NHibernate 3.3.1, and I get this exception when session factory is created:
Could not find the property 'InsertDate', associated to the field
'insertDate', in class 'XXXX'
Why is is happening & how can I change mapping in order to get rid of the exception?
EDIT: Below answer is completly correct. But for those of you that don't need/don't want to have a property, and only field, there's another solution:
set name attribute to field name (in my case it is insertDate) and remember to have correct column name
<property name="insertDate" column="InsertDate" access="field.camelcase" update="false" />
It is case sensitivity, this will work.
<property name="insertDate" column="InsertDate" update="false" />
Looks like in release 3.1.0, there was a breaking change
NH today accepts code below. It would be better if this would throw - it causes problem when configurate NH (or 3rd party tools) other ways than by hbm, using the property name (or memberinfo) of the public interface.
[hbm]
<property name="Name" access="field.camelcase" />
[code]
string name;
public virtual string SomeThingCompletelyDifferent{
get {return name;}
set{name=value;}
}
Note: This will be a breaking change.
ps - updated answer to remove reference to use Property with private set as this was not what was being looked for and above breaking change is more relevant.

Coldfusion ORM 9.0.1 - Error while resolving relationship

I got this example from the adobe coldfusion documentation, some of the names are changed but everything else is the same, unless I am just so frustrated that I have missed a letter.
user.cfc:
/**
*#persistent
*/
component
{
property name="id" fieldtype="id" generator="native";
property name="userName" type="string" length="100";
property name="Credential" fieldtype="one-to-one" cfc="model.user.credentials";
}
credentials.cfc:
/**
*#persistent
*/
component
{
property name="id" fieldtype="id" generator="foreign" params="{property='userinfo'}";
property name="userinfo" fieldtype="one-to-one" cfc="model.user.user" constrained="true";
property name="passwordHash" type="string";
}
no matter how I word it, after searching many sites, I still get a error of:
Error while resolving the relationship Credential in cfc user. Check the column mapping for this property.
I have checked that both cfcs are accessible by coldfusion by removing the one-to-one properties and the tables have been created successfully.
I am using SQL Server 2008 with Coldfusion 9.0.1 under Apache 2.2 web server.
I am new to ORM and Hibernate but have successfully created different types of relationships and will confess to a less then expert level of coldfusion.
Thanks, this is really bothering me as this came directly from the coldfusion documentation.
Do you have a mapping for model?
If not, add one, or you could try:
property name="Credential" fieldtype="one-to-one" cfc="credentials";

Map a property to the latest entry in NHibernate

Let's say my domain looks like this:
I have an object, Vehicle, that has an OdometerReading property.
An OdometerReading has the Miles & Date (when it was read).
I need to keep a history of all OdometerReadings for the Vehicle in the database, but don't want the entire odometer history to belong to the Vehicle object. What I would like is for the OdometerReading property map to the most recent OdometerReading entry out of the database.
I thought about mapping the whole collection of OdometerReadings to the Vehicle, and having a dynamic property called CurrentOdometerReading that would order them and return the latest one, but I don't need the whole collection under the Vehicle in my domain, and it seems like I would be getting more data out of the database than I need.
Is that possible with NHibernate? How would I map such a thing?
There are a few ways of doing this depending on what you want your domain model to look like. My preferred choice is to use a custom collection type, for example IOdometerReadingCollection, which you can add extra methods to. In this case it might be something like:
public interface IOdometerReadingCollection : IList<OdometerReading>
{
OdometerReading Latest { get; }
}
This way you can do:
OdometerReading reading = vehicle.OdometerReadings.Latest;
which I prefer to:
OdometerReading reading = vehicle.LatestOdometerReading;
There's lots of documentation about custom collections, which you can find with a simple google search.
If this approach isn't for you there are other options. You may be able to use a property with a formula (I'm not sure if that works with complex types?), or a regular NHibernate association where you'd have the key of the latest OdometerReading on your Vehicle mapping. As you also mentioned you could just load all the OdometerReadings, which depending on your use case might actually be fine.
I hope this helps, or at least points you in the right direction.
There is a "where" clause that you can put in your collection mapping. Check the reference documentation.
I would map the OdometerReading property as a component, then use a named query to ensure it's populated with the latest reading out of the database. (In this example, you'd have a sql-query with a name of "vehicle" that does the SQL to load the Vehicle columns along with the latest Odometer reading)
<class name="Vehicle">
<property name="Type" not-null="true"/>
<component name="OdometerReading">
<property name="Miles" />
<property name="Date" />
</component>
<loader query-ref="vehicle"/>
</class>