m2m failing to work (or even error)

28 views
Skip to first unread message

Raymond Camden

unread,
Apr 8, 2013, 9:55:02 AM4/8/13
to cf-or...@googlegroups.com
I've got an odd situation with a entity that includes a m2m property. I can set various fields on the entity just fine. When I updated my code to save values in a m2m relationship, it didn't throw an error, but didn't persist in the join table. My CFC is called content and here is the m2m property:

property name="products" fieldType="many-to-many" cfc="product" linktable="content_product" 
fkcolumn="contentidfk" inversejoincolumn="productidfk" lazy="true" singularname="product";


Here is the code doing the adds:

for(var i=1; i<=listLen(data.product); i++) {
var productid = listGetAt(data.product, i);
var product = variables.dbService.getContent("product", productid);
content.addProduct(product);
writelog("added product " & product.getName());
}

And I definitely get proper log messages. If I do a cfdump of the entity, it looks perfect. Yet when it comes time to actually persist, every other part of the entity is stored correctly except for the joined data. Any ideas? 

Seth Johnson

unread,
Apr 8, 2013, 10:51:50 AM4/8/13
to cf-or...@googlegroups.com

Ray,

Have you tried setting both sides of the relationship?

Product.addcontent(content);
Content.addproduct(product);

Seth

--
You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cf-orm-dev+...@googlegroups.com.
To post to this group, send email to cf-or...@googlegroups.com.
Visit this group at http://groups.google.com/group/cf-orm-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Raymond Camden

unread,
Apr 8, 2013, 10:58:14 AM4/8/13
to cf-or...@googlegroups.com
Yep. I'm doing it in a method in content.cfc.

public function addProduct(p) {
if(!hasProduct(p)) {
arrayAppend(products, p);
arrayAppend(p.getContent(), this);
writelog("I really fucking added it.");

Raymond Camden

unread,
Apr 8, 2013, 10:58:42 AM4/8/13
to cf-or...@googlegroups.com
Um - pardon the french there. 

Cameron Childress

unread,
Apr 8, 2013, 11:20:38 AM4/8/13
to cf-or...@googlegroups.com
I remember having a little bit of difficulty getting many-to-many working at one point. This was on Railo, but it may translate over. You don't show it, but I assume you've also defined a m2m in product that points back to content?

A similar m2m linking permissions to groups in my code looks like this:

The most significant thing (I think) on the other side was including the inverse=true.

-Cameron


--
You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cf-orm-dev+...@googlegroups.com.
To post to this group, send email to cf-or...@googlegroups.com.
Visit this group at http://groups.google.com/group/cf-orm-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Cameron Childress
--
p:   678.637.5072
im: cameroncf

Matt Quackenbush

unread,
Apr 8, 2013, 11:22:25 AM4/8/13
to cf-or...@googlegroups.com
Heh. :-)


Raymond Camden

unread,
Apr 8, 2013, 11:30:48 AM4/8/13
to cf-or...@googlegroups.com
Here is the entire product.cfc:

component persistent="true" {

property name="id" generator="native" ormtype="integer" fieldtype="id";

property name="name" ormtype="string";

property name="content" fieldtype="many-to-many" cfc="content"
  type="array" singularname="content" linktable="content_product"
  inverse="true";

function addContent(c) {
c.addProduct(this);

Cameron Childress

unread,
Apr 8, 2013, 11:40:58 AM4/8/13
to cf-or...@googlegroups.com
I may not have much more for you here. This is where I usually start just thowing stuff up against the wall and running tests to see if it starts working.

The first thing I would probably try would be adding fkcolumn and inversejoincolumn to the product side. I also notice that both the plural and singular name are the same for "content", which might trip something up. You might try changing the name="contents" or something to make sure that's not causing a problem.

Someone else may have additional suggestions.

-Cameron

Raymond Camden

unread,
Apr 8, 2013, 11:46:27 AM4/8/13
to cf-or...@googlegroups.com
Added, also removed the singular property on product, still no go. GRR HULK SMASH ORM.

Raymond Camden

unread,
Apr 8, 2013, 12:26:44 PM4/8/13
to cf-or...@googlegroups.com
Wow, so this is... messed up.

On a whim I turned off the auto flush in ORM settings. 
In my service component I wrapped the entitySave in a transaction.

And boom - I got an error right away:

coldfusion.orm.PersistentTemplateProxy cannot be cast to java.util.Collection

Googling for this turned up people who were putting simple values in for props that should be other entities. Here is where things get interesting.

Above my code to set products into the entity I had this:

content.setSegment(data.segment);

content.segment is a many to one:

property name="segment" fieldType="many-to-one" cfc="segment" fkcolumn="segmentidfk" lazy="false";

I've got a utility method in content.cfc that handles this:

public any function setSegment(id) {
var segment = entityLoadByPk("segment", id);
variables.segment = segment;
writelog("added a segment");
segment.setContent(this);
}

Segment.cfc has:

property name="content" fieldType="one-to-many" cfc="content" fkcolumn="segmentidfk" inverse="true";

So that seems to imply that my method didn't work. But - note the log - it fires. I also added a dump before the transaction and I see the right value in the segment property.

Cameron Childress

unread,
Apr 8, 2013, 12:48:44 PM4/8/13
to cf-or...@googlegroups.com
When I override a setter with a method that receives an ID rather than the full object, I like to rename it to make sure I didn't break anything along the way. since your error may have to do with setting simple props where there should be ID, is sounds particularly suspect to me that perhaps you are setting an ID into a setter that expects a full entity. It might not be the Segment entity though. It could be somewhere else in your object graph.

So, I'd usually do something like:

public any function setSegmentID(id) {
  setSegment(entityLoadByPk("segment", arguments.id));
}

This way you can choose to set a relationship by ID or set by entity where needed as long as you follow the naming convention. I wonder if somewhere (maybe in an inverse call) you're accidentally setting an entity vs id.

-Cameron


--
You received this message because you are subscribed to the Google Groups "cf-orm-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cf-orm-dev+...@googlegroups.com.
To post to this group, send email to cf-or...@googlegroups.com.
Visit this group at http://groups.google.com/group/cf-orm-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Raymond Camden

unread,
Apr 8, 2013, 1:10:40 PM4/8/13
to cf-or...@googlegroups.com
I tried that, but no go:

public any function setSegmentById(id) {
var segment = entityLoadByPk("segment", id);
variables.segment = segment;
writelog("added a segment");
segment.setContent(this);
}

Seems like a smart change anyway. On the segment side, I've got nothing but the definition.

Raymond Camden

unread,
Apr 8, 2013, 1:13:39 PM4/8/13
to cf-or...@googlegroups.com
Ok, I've narrowed it down to this line in setSegmentById

segment.setContent(this);



On Monday, April 8, 2013 8:55:02 AM UTC-5, Raymond Camden wrote:

Raymond Camden

unread,
Apr 8, 2013, 1:19:46 PM4/8/13
to cf-or...@googlegroups.com
Which still doesn't help me. If I dump out segment, it looks perfect. Ditto for content.

Cameron Childress

unread,
Apr 8, 2013, 1:21:56 PM4/8/13
to cf-or...@googlegroups.com
Could be something else that you think is unrelated. This is where I usually strip out all the other entities and code and simplify to only the area you are focusing on. See if the error still happens. You may have already done that. I'm just running out of ideas. :)

-Cameron

Raymond Camden

unread,
Apr 8, 2013, 1:31:30 PM4/8/13
to cf-or...@googlegroups.com
Well, I've got everything else but that now. Still errors. 

Raymond Camden

unread,
Apr 8, 2013, 1:35:27 PM4/8/13
to cf-or...@googlegroups.com
Holy crap. I forgot.

Content is many to one to segment.

On content, I need to setSegment.
On Segment, I need to *add* content.

Thank you, oh obscure error messages for being incredibly not helpful.

(And thanks all in the thread for getting me there.)
Reply all
Reply to author
Forward
0 new messages