log4net: How to set logger file name dynamically? - dynamic

This is a really common question, but I have not been able to get an answer to work. Here is my configuration file:
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="CraneUserInterface.log" />
<appendToFile value="true" />
<maxSizeRollBackups value="90" />
<rollingStyle value="Size" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFile" />
</root>
But I need to determine the actual logging file name at run time. I found a nice example here, but when I try to loop through the collection returned by the call to GetIterators(), I find that that collection is empty.
I need to change the name "CraneUserInterface.log" to "CraneUserInterface_1.log", or 2, or 3, depending on something the program reads at run time. How can I do that?
Here's my first pass at using the code presented in that sample:
static bool ChangeLogFileName(string AppenderName, string NewFilename)
{
// log4net.Repository.ILoggerRepository RootRep;
// RootRep = log4net.LogManager.GetRepository();
log4net.Repository.ILoggerRepository RootRep = m_logger.Logger.Repository;
foreach (log4net.Appender.IAppender iApp in RootRep.GetAppenders())
{
string appenderName = iApp.Name;
if (iApp.Name.CompareTo(AppenderName) == 0
&& iApp is log4net.Appender.FileAppender)
{
log4net.Appender.FileAppender fApp = (log4net.Appender.FileAppender)iApp;
fApp.File = NewFilename;
fApp.ActivateOptions();
return true; // Appender found and name changed to NewFilename
}
}
return false; // appender not found
}
Thanks very much!

What about to use "%property" to define a dynamic 'tag' to the file name (at runtime) ?
<file type="log4net.Util.PatternString" value="~/App_Data/%property{LogName}" />
Explained here: Best way to dynamically set an appender file path

you can use this function :
in this function first get file location that you set in webconfig and after that you can add any path that you want ! like Date ! our Customer ! or .....
WebConfig:
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\\t4\\"/>
<appendToFile value="true"/>
<rollingStyle value="Composite"/>
<datePattern value="_yyyy-MM-dd.lo'g'"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="1MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date User:%identity IP:%X{addr} Browser: %X{browser} Url: %X{url} [%thread] %-5level %c:%m%n"/>
</layout>
</appender>
Function:
public static void ChangeFileLocation(string _CustomerName,string _Project)
{
XmlConfigurator.Configure();
log4net.Repository.Hierarchy.Hierarchy h =(log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
foreach (IAppender a in h.Root.Appenders)
{
if (a is FileAppender)
{
FileAppender fa = (FileAppender)a;
string sNowDate= DateTime.Now.ToLongDateString();
// Programmatically set this to the desired location here
string FileLocationinWebConfig = fa.File;
string logFileLocation = FileLocationinWebConfig + _Project + "\\" + _CustomerName + "\\" + sNowDate + ".log";
fa.File = logFileLocation;
fa.ActivateOptions();
break;
}
}
}
and result like this : C:\t4\TestProject\Customer1\Saturday, August 31, 2013.log

Related

New custom property in properties panel extension not reflect in bpmn diagram xml

I’m adding some custom properties in the property panel like below,
I diable Id property in the General tab. Adding 2 new tabs Input and Output.
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
<bpmn2:process id="Process_1" isExecutable="false">
<bpmn2:startEvent id="StartEvent_1">
<bpmn2:outgoing>Flow_0n4p9tk</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:task id="Activity_0d872w2">
<bpmn2:incoming>Flow_0n4p9tk</bpmn2:incoming>
</bpmn2:task>
<bpmn2:sequenceFlow id="Flow_0n4p9tk" sourceRef="StartEvent_1" targetRef="Activity_0d872w2" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
<bpmndi:BPMNEdge id="Flow_0n4p9tk_di" bpmnElement="Flow_0n4p9tk">
<di:waypoint x="448" y="258" />
<di:waypoint x="500" y="258" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="412" y="240" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0d872w2_di" bpmnElement="Activity_0d872w2">
<dc:Bounds x="500" y="218" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>
See 2 screenshots I added new control in the property panel but XML not showing me if I download the diagram. What am I missing in it?
Note: My code is the same replica of the BPMN custom property panel example
I resolved the issue. I able to set input-output parameter in BPMN diagram using the following code,
set: function setValue(element, values, node) {
var b_obj = getBusinessObject(element);
var selectedValues = {};
selectedValues = values;
prop[_id] = selectedValues[_id];
var selectedName = dropdownOptions[parseInt(prop[_id])].name;
var bo = cmdHelper.updateBusinessObject(element, b_obj, prop);
var selectedInputParameter = bpmnFactory.create('camunda:InputParameter', {
name: selectedName,
value: prop[_id]
});
var inputOutput = bpmnFactory.create('camunda:InputOutput', {
inputParameters: [selectedInputParameter]
});
b_obj.extensionElements = b_obj.extensionElements || bpmnFactory.create('bpmn:ExtensionElements');
b_obj.extensionElements.get('values').push(inputOutput);
return bo;
}
I got a hint from here

Get attributes from XML with more than one namespaces

I have this XML:
<?xml version="1.0" encoding="UTF-8" ?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="3.3" Serie="NG" Folio="55" Fecha="2017-08-02T20:08:58" FormaPago="99" SubTotal="5861.73" Descuento="778.38" Moneda="MXN" Total="5083.35" TipoDeComprobante="N" MetodoPago="PUE" LugarExpedicion="08400" Sello="yAfYBR0/bvvFgq/hNL+DSTTPt+kNtsE3DzxagXvG0M/alfaUrjp73IySCEBHIeo4nNF4uoscqnRoIowwfQPnNwC4LL6iD77rfykF2hq+i6VzqAlvbx0aawZUAcJpjNVWyS3zjfa3rYeU1TpNBrhSuU8r+4BoBz3jr1pB7yyCIm4JbwzNqy0TvTjD1XXnpy6v74+eqIoZqWZoi3CyiCqMS2B3FEfDMiXTfVlZ/3/evLYc5WvFPpBsm61I+SBID/rHhJvLQLjJDUX7Myt177N41xptITkIKQCJAIV6XN7mRGJTHKA3h3F7tSZaei8+LeONO9ZtlUZGw4dzLhrpNk/tuA==" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd">
<cfdi:Emisor Rfc="BBBBBB" Nombre="S.A. de C.V." RegimenFiscal="601" />
<cfdi:Receptor Rfc="AAAAAAAA" Nombre="AZUCENA SAN " UsoCFDI="P01" />
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="84111505" Cantidad="1" ClaveUnidad="ACT" Descripcion="Pago de nómina" ValorUnitario="5861.73" Importe="5861.73" Descuento="778.38" />
</cfdi:Conceptos>
<cfdi:Complemento>
<nomina12:Nomina xmlns:nomina12="http://www.sat.gob.mx/nomina12" Version="1.2" TipoNomina="O" FechaPago="2017-07-16" FechaInicialPago="2017-07-01" FechaFinalPago="2017-08-15" NumDiasPagados="15.000" TotalPercepciones="5861.73" TotalDeducciones="778.38" xsi:schemaLocation="http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd">
<nomina12:Emisor RegistroPatronal="Y6844621109" />
<nomina12:Receptor Curp="SASA850203MDFNNZ06" NumSeguridadSocial="39058519115" FechaInicioRelLaboral="2012-09-14" Antigüedad="P254W" TipoContrato="01" Sindicalizado="No" TipoJornada="03" TipoRegimen="02" NumEmpleado="073" Departamento="VENTAS" Puesto="GERENTE TIENDAS" RiesgoPuesto="1" PeriodicidadPago="04" SalarioBaseCotApor="183.33" SalarioDiarioIntegrado="356.57" ClaveEntFed="DIF" />
<nomina12:Percepciones TotalSueldos="5861.73" TotalGravado="5089.21" TotalExento="772.52">
<nomina12:Percepcion TipoPercepcion="001" Clave="0001" Concepto="Sueldos" ImporteGravado="1026.69" ImporteExento="0.00" />
<nomina12:Percepcion TipoPercepcion="020" Clave="0008" Concepto="Prima dominical" ImporteGravado="0" ImporteExento="78.36" />
<nomina12:Percepcion TipoPercepcion="001" Clave="0020" Concepto="Vacaciones" ImporteGravado="1466.69" ImporteExento="0" />
<nomina12:Percepcion TipoPercepcion="021" Clave="0009" Concepto="Prima Vacacional" ImporteGravado="0" ImporteExento="458.33" />
<nomina12:Percepcion TipoPercepcion="038" Clave="0022" Concepto="Bonos" ImporteGravado="1000" ImporteExento="0" />
<nomina12:Percepcion TipoPercepcion="028" Clave="0010" Concepto="Comisiones" ImporteGravado="1360" ImporteExento="0" />
<nomina12:Percepcion TipoPercepcion="019" Clave="0007" Concepto="Horas extras" ImporteGravado="235.83" ImporteExento="235.83">
<nomina12:HorasExtra Dias="2" TipoHoras="01" HorasExtra="2" ImportePagado="235.83" />
<nomina12:HorasExtra Dias="1" TipoHoras="02" HorasExtra="1" ImportePagado="235.83" />
</nomina12:Percepcion>
</nomina12:Percepciones>
<nomina12:Deducciones TotalOtrasDeducciones="122.73" TotalImpuestosRetenidos="655.65">
<nomina12:Deduccion TipoDeduccion="002" Clave="0013" Concepto="ISR" Importe="655.65" />
<nomina12:Deduccion TipoDeduccion="001" Clave="0012" Concepto="IMSS" Importe="122.73" />
</nomina12:Deducciones>
</nomina12:Nomina>
<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/timbrefiscaldigital/TimbreFiscalDigitalv11.xsd" Version="1.1" UUID="2A73927D-7E57-40C7-9A8B-2E062560AC9E" FechaTimbrado="2017-08-02T19:52:07" SelloCFD="yAfYBR0/bvvFgq/hNL+DSTTPt+kNtsE3DzxagXvG0M/alfaUrjp73IySCEBHIeo4nNF4uoscqnRoIowwfQPnNwC4LL6iD77rfykF2hq+i6VzqAlvbx0aawZUAcJpjNVWyS3zjfa3rYeU1TpNBrhSuU8r+4BoBz3jr1pB7yyCIm4JbwzNqy0TvTjD1XXnpy6v74+eqIoZqWZoi3CyiCqMS2B3FEfDMiXTfVlZ/3/evLYc5WvFPpBsm61I+SBID/rHhJvLQLjJDUX7Myt177N41xptITkIKQCJAIV6XN7mRGJTHKA3h3F7tSZaei8+LeONO9ZtlUZGw4dzLhrpNk/tuA==" NoCertificadoSAT="20001000000300022323" SelloSAT="FXfgRBNhWla+53sM4eGnMFbbmQFb6EIaWMt3GMaqXJn9XPxQ5DVNuz7oTJ+yUZV0ObM5myqzzsI4Zvx3g==" RfcProvCertif="EME000602QR9" />
</cfdi:Complemento>
</cfdi:Comprobante>
And I need to get the values of some attributes, I can get attributes from the node cfdi:Comprobante, but when I try to read an attribute from tfd:TimbreFiscalDigital I get object reference not set to an instance of an object.
Here is the code I'm using:
Dim doc As XmlDocument = New XmlDocument()
doc.Load("C:\Users\s_osr\Desktop\EjemplosCFDINomina12\HorasExtras\SIGN_XML_COMPROBANTE_3_0.xml")
Dim managerdoc As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable)
managerdoc.AddNamespace("cfdi", doc.DocumentElement.NamespaceURI)
managerdoc.AddNamespace("tfd", doc.DocumentElement.NamespaceURI)
Dim Sello As String = doc.SelectSingleNode("/cfdi:Comprobante/#Sello", managerdoc).InnerText
Dim SelloSat As String = doc.SelectSingleNode("/cfdi:Comprobante/cfdi:Complemento/tfd:TimbreFiscalDigital/#SelloSAT", managerdoc).InnerText
Sello is working, but I can´t get SelloSAT.
UPDATE:
Thanks to #Kaiido for the solution, the uri string for the second namespace:
managerdoc.AddNamespace("tfd", "http://www.sat.gob.mx/TimbreFiscalDigital")

How can I highlight syntax in Microsoft OneNote 2013?

I want to highlight syntax for my programming language of choice (proprietary) in Microsoft OneNote 2013 with a macro or script. I found a free Macro creator for MS OneNote '13 that allows creation of custom macros called "OneTastic". I created a macro that is given two arrays with lists of predefined words associated with different colors to give each list (ex: List 1 words = blue, list 2 words = orange, etc.)
API: https://www.omeratay.com/onetastic/docs/
Problem: The search logic is finding words inside of bigger words, like "IN" inside of the word "domain" (domaIN). My code is below:
<?xml version="1.0" encoding="utf-16"?>
<Macro name="CCL TEST 3" category="Color" description="" version="10">
<ModifyVar name="KEYWORDS1" op="set">
<Function name="String_Split">
<Param name="string" value="drop create program go %i declare call set end END execute else elseif protect constant curqual of subroutine to noconstant record free range in is protect define macro endmacro" />
<Param name="delimiter" value=" " />
</Function>
</ModifyVar>
<ModifyVar name="counter" op="set" value="0" />
<WhileVar name="counter" op="lt">
<Function name="Array_Length">
<Param name="array" var="KEYWORDS1" />
</Function>
<IsRootOp />
<ModifyVar name="keyword" op="set" var="KEYWORDS1">
<RightIndex var="counter" />
</ModifyVar>
<For each="Text">
<That hasProp="value" op="eq" var="keyword" />
<ModifyProp name="fontColor" op="set" value="blue" />
</For>
<ModifyVar name="counter" op="add" value="1" />
</WhileVar>
<ModifyVar name="KEYWORDS2" op="set">
<Function name="String_Split">
<Param name="string" value="datetimefind datetimediff cnvtdatetime cnvtalias format build concat findfile error alterlist alter initrec cnvtdate esmError echo max min avg sum count uar_get_code_meaning mod substring size trim hour day isnumeric expand locateval cnvtstring fillstring btestfindstring logical uar_get_code_display uar_get_meaning_by_codeset UAR_GET_CODE_BY sqltype cnvtreal echorecord cnvtupper cnvtlower cnvtdatetimeutc abs datetimediff year julian btest decode evaluate findstring asis replace validate nullterm parser value uar_timer_create uar_CreatePropList uar_SetPropString uar_CloseHandle uar_Timer_Destroy uar_Timer_Stop build2 patstring piece cnvtalphanum timestampdiff" />
<Param name="delimiter" value=" " />
</Function>
</ModifyVar>
<ModifyVar name="counter2" op="set" value="0" />
<WhileVar name="counter2" op="lt">
<Function name="Array_Length">
<Param name="array" var="KEYWORDS2" />
</Function>
<IsRootOp />
<ModifyVar name="keyword" op="set" var="KEYWORDS2">
<RightIndex var="counter2" />
</ModifyVar>
<For each="Text">
<That hasProp="value" op="eq" var="keyword" />
<ModifyProp name="fontColor" op="set" value="orange" />
</For>
<ModifyVar name="counter2" op="add" value="1" />
</WhileVar>
</Macro>
There is no such inbuilt feature available in OneNote but you can do it.
Use Visual Studio Code, it's free. Turn on right text copy/pasting. Write your code in in VS code. Copy it. It'll paste exactly as you see. Colors and all.
While this does not use VBA, I use and love the add-in NoteHightlight2016
If you don't find a language you can go through and add your own. I've added the Excel Formula keywords to the languages supported and I believe it is a bit easier than creating in OneTastic, which I also use and love.

Dynamics CRM- update record of contact entity

I have created contact record using ASP.NET. Now I need to Check if the contact record exists. If exists, update the same record. Through advance find have downloaded FetchXML and added to my FetchXML variable. Please suggest the logic. Below is my code.
// Establish a connection to crm and get the connection proxy
string connectionString = "xyz; Username= xyz ;Password=xyz";
CrmConnection connect = CrmConnection.Parse(connectionString);
OrganizationService service;
using (service = new OrganizationService(connect))
{
WhoAmIRequest request = new WhoAmIRequest();
Guid userId = ((WhoAmIResponse)service.Execute(request)).UserId;
ContactDetails contact = new ContactDetails();
//Check if the contact record exists . If exists , update the same record.
//Fecthxml query
string fetchXml = #" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='contact'>
<attribute name='fullname' />
<attribute name='parentcustomerid' />
<attribute name='telephone1' />
<attribute name='emailaddress1' />
<attribute name='contactid' />
<order attribute='fullname' descending='false' />
<filter type='and'>
<condition attribute= 'mobilephone' operator='not-null' />
</filter>
</entity>
</fetch>" ;
FetchExpression query = new FetchExpression(fetchXml);
EntityCollection results = service.RetrieveMultiple(query);
if (results.Entities.Count > 0)
{
Entity contactRecord = results[0];
contactRecord["firstname"] = contactInfo.FirstName;
contactRecord["lastname"] = contactInfo.LastName;
contactRecord["emailaddress1"] = contactInfo.EmailId;
contactRecord["mobilephone"] = contactInfo.MobilePhone;
contactRecord["address1_line1"] = contactInfo.Street1;
contactRecord["address1_line2"] = contactInfo.Street2;
contactRecord["address1_line3"] = contactInfo.Street3;
contactRecord["address1_city"] = contactInfo.City;
service.Update(contactRecord);
}
//Else, Create the contact record
else
{
Entity entity = new Entity();
entity.LogicalName = "contact";
entity["firstname"] = contactInfo.FirstName;
entity["lastname"] = contactInfo.LastName;
entity["emailaddress1"] = contactInfo.EmailId;
entity["mobilephone"] = contactInfo.MobilePhone;
entity["address1_line1"] = contactInfo.Street1;
entity["address1_line2"] = contactInfo.Street2;
entity["address1_line3"] = contactInfo.Street3;
entity["address1_city"] = contactInfo.City;
entity["address1_stateorprovince"] = contactInfo.State;
entity["address1_country"] = contactInfo.Country;
entity["spousesname"] = contactInfo.SpouseName;
entity["birthdate"] = contactInfo.Birthday;
entity["anniversary"] = contactInfo.Anniversary;
//Create entity gender with option value
if (contactInfo.Gender == "Male")
{
entity["gendercode"] = new OptionSetValue(1);
}
else
{
entity["gendercode"] = new OptionSetValue(2);
}
//entity["familystatuscode"] = contactInfo.MaritalStatus;
if (contactInfo.MaritalStatus == "Single")
{
entity["familystatuscode"] = new OptionSetValue(1);
}
else
{
entity["familystatuscode"] = new OptionSetValue(2);
}
service.Create(entity);
}
}
// Create the entity
your logic seems ok, with the exception of the FectchXML query. The way you have your code, you will always end up updating the first record retrieved that has its mobilephone field filled. That does not seem a good way to check if a contact already exists.
I suggest you to change the filter of your fetch. In your filter condition you have to use an attribute that represents uniqueness for all contacts.
Apart of this your code looks ok.
Like nunoalmeieda says, you need to have a better way to ascertain if the Contact already exists. A common way of identifying if the Contact already exists would be to check if the email address already exists as it is very unlikely that two people will have the same email address.
I have updated your basic code to show how it is done with FetchXML.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name='fullname' />
<attribute name='parentcustomerid' />
<attribute name='telephone1' />
<attribute name='emailaddress1' />
<attribute name='contactid' />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="emailaddress1" operator="eq" value=contactInfo.EmailId />
</filter>
</entity>
</fetch>
The logic here is that I am checking if the value of emailaddress1 (field in the contact entity of CRM) is equal to the value of your contactInfo.EmailId. I am assuming that contactInfo is the record that you get from ASP.NET.
The rest of your code is fine (I have formatted it a bit to make the question more readable).

ORM - Linked Table Error

I'm working on a blog application using ColdBox 3.5 and ColdFusion 10 ORM, and I'm randomly getting following error message:
Error Type: Application : [N/A]
Error Messages: Exception in Hibernate operation.
Either the updated/deleted row does not exist or the session contained stale data.
Root cause :org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Entry#297e1bfa369cf17501369d26ffae00a4]
/model/entry/Entry.cfc:
component
persistent="true"
table="Entry"
output="false"
{
// primary key
property name="entryID" fieldtype="id" ormtype="string" type="string" length="32" generator="uuid";
// properties
property name="title" fieldtype="column" ormtype="string" type="string" length="100" notnull="true";
property name="alias" fieldtype="column" ormtype="string" type="string" length="100" notnull="true";
property name="body" fieldtype="column" ormtype="string" type="string" sqltype="nvarchar(max)" notnull="true";
property name="allowComments" fieldtype="column" ormtype="boolean" type="boolean" sqltype="bit" dbdefault="1" default="true" notnull="true";
property name="released" fieldtype="column" ormtype="boolean" type="boolean" sqltype="bit" dbdefault="1" default="true" notnull="true";
property name="releasedDate" fieldtype="column" ormtype="timestamp" type="date";
property name="addDate" fieldtype="timestamp" ormtype="timestamp" type="date";
// relations
property name="categories" fieldtype="many-to-many" cfc="model.category.Category" linktable="EntryCategory" fkcolumn="entryID" inversejoincolumn="categoryID" singularname="category" cascade="all" lazy="true";
property name="comments" fieldtype="one-to-many" cfc="model.entryComment.EntryComment" fkcolumn="entryID" singularname="comment" cascade="all-delete-orphan";
property name="user" fieldtype="many-to-one" cfc="model.user.User" fkcolumn="userID" notnull="true" cascade="save-update";
property name="views" fieldtype="one-to-many" cfc="model.entryView.EntryView" fkcolumn="entryID" singularname="view" cascade="all-delete-orphan";
// validation
this.constraints = {
"title" = {"required" = true},
"body" = {"required" = true},
"allowComments" = {"required" = true, type="boolean"},
"released" = {"required" = true, type="boolean"},
"categories" = {size=1},
"user" = {type="component"}
};
}
/model/category/Category.cfc:
component
persistent="true"
table="Category"
schema="system"
output="false"
{
// primary key
property name="categoryID" fieldtype="id" ormtype="string" type="string" length="32" generator="uuid";
// properties
property name="name" fieldtype="column" ormtype="string" type="string" length="50" notnull="true";
property name="alias" fieldtype="column" ormtype="string" type="string" length="50" notnull="true";
property name="description" fieldtype="column" ormtype="string" type="string" default="" length="200";
property name="addDate" fieldtype="timestamp" ormtype="timestamp" type="date";
property name="active" fieldtype="column" ormtype="boolean" type="boolean" sqltype="bit" dbdefault="1" default="true" notnull="true";
// relations
property name="entries" fieldtype="many-to-many" cfc="model.entry.Entry" linktable="EntryCategory" fkcolumn="categoryID" inversejoincolumn="entryID" lazy="true" cascade="all" singularname="entry" inverse="true";
// validation
this.constraints = {
"name" = {"required" = true},
"active" = {"required" = true, type="boolean"}
};
}
Here's the code that I'm running:
<cfscript>
entry = entityNew("Entry", {
"title" = "test",
"body" = "test",
"alias" = "test",
"allowComments" = 0,
"released" = 0,
"user" = entityLoadByPK("User", "297e1bfa3697d377013697f53ca10084")
});
// works 1 out of 5 times
entry.setCategories([entityLoadByPK("Category", "297e1bfa36986e69013698c3e54f000d")]);
// works every time
//entry.setCategories(entityLoad("Category", "297e1bfa36986e69013698c3e54f000d"));
//entry.setCategories(entityLoad("Category"));
entitySave(entry);
ormFlush();
</cfscript>
Notice the sections labeled as "works 1 out of 5 times" and "works every time". I don't get what I'm doing wrong. I have other objects similar to these where they use linked table and I'm getting similar error messages. I've reviewed the SQL log. The error appears to occur when it gets ready to insert to EntryCategory table. Any ideas?
Use HQL and use where ID in (?). That works very well.
If the entity already has an array, use ArrayClear() first.
UPDATE:
categories = ormExecuteQuery("from Category where Id IN (:Ids)",
{Ids=listToArray(FORM.categoryIDs)});
entry.setCategories(categories);