Re: ORM question
Hi Barney, After trying to find the answer to the question for almost a day I was afraid that the answer is no but just wanted to be sure :) The reason I want only a few is for display purposes. Just to give some indication to users the type of subcategories exists. While I like the idea of ORM, I'm afraid to use it in a heavy production environment because I don't really know the guts of it and may introduce problems that are hard to debug. I'm starting a new project and I'm on the fence. I'm just learning it and don't want to jeopardize it because my inexperience (with ORM) plus (at least initially) will take me more time to code than using direct SQL, I know SQL, it comes very easy to work with and (for the most part) I understand, can optimize and test it. Thanks Victor On Sat, Jan 16, 2010 at 11:58 PM, Barney Boisvert bboisv...@gmail.com wrote: The short answer is no. The long answer is that yeah, you can do a whole bunch of hacking around to make it work like that (or at least APPEAR to work like that), but it's a mess. I can't think of a case when you wouldn't be better off a) just constraining the loop over the subcategories when you go to use them, or b) using a separate query for subcategoies rather than a relationship traversal. What's your reason for wanting to only get three? cheers, barneyb On Sat, Jan 16, 2010 at 8:49 PM, Victor Moore victor.mo...@gmail.com wrote: Hi, I have the following cfc: component output=false persistent=true entityname=Category table=category { property name=catID column=cat_id; property name=name ; property name=subCategories fieldtype=one-to-many cfc=SubCategory singularname=SubCategory fkcolumn=cat_id cascade=all lazy=extra; } is it possible to retrieve only 3 subCategories when calling entityLoad (Category)? Thanks Victor ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329738 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
RE: More Efficient (Faster) Method
Well Dave - First, thanks for not restraining yourself. If I wanted people to restrain themselves - I probably wouldn't have asked the question in a public forum. So, I appreciate you chiming in. ;) Your quote - and the article it links to - more or less hits the nail on the head - and gets at what I was trying to ask. (Although maybe not as clearly as I wanted) Premature optimization is a phrase used to describe a situation where a programmer lets performance considerations affect the design of a piece of code. This can result in a design that is not as clean as it could have been or code that is incorrect, because the code is complicated by the optimization and the programmer is distracted by optimizing. So - what I was more or less asking about my code - was more or less - Was it good design? Or should I have thought of it a completely different way? And of course - in thinking of it a different way - could I have made it faster (or improved performance). To me - Good Design is both clean - AND fast. I understand there is give and take - I am trying to find out what those are in regards to this scenario. Now I will come out and say it - I don't consider myself a programmer. I'm the Half-Breed - the Graphic Designer who has found himself becoming a programmer out of necessity. I have no formal training other than reading the CF-Wack a few dozen times. I am continually trying to learn new things and improve my code... So that being said - - Leigh's approach is completely different from what I would have thought of -and I am really appreciative of the insight- and in the interest of learning through enhancing application performance I am asking questions about whether that is faster or a truly better approach. I myself have NO idea. So - using that concept of 100 years of Dates stored in a DB - is that a better way to design an application rather than using/looping DateAdd()? (Especially If you only need to get at 30-90 days of dates at a time) I certainly don't know - so I thought I would ask to see what Leigh and Others think? To myself, it seems completely counter-intuitive to re-create a calendar. But to add another quote We don't know what we don't know. And - I know, I don't know. Ya know? I would also add - that this probably doesn't exactly fall into the Premature category. The code is completed and it works. Now am I wondering the different ways it could or should be improved upon... And more importantly - if there is a general consensus among the group as to what I should NOT do. There are some very simple things happening in this code - and methods/approaches I use on a regular basis. So I figured this would be a good piece of code for me to see if others have input. Does that make sense? I mean - what I really want here is either: 1) Boy, it's pretty straight forward, changing it really won't get you much if anything. - or - 2) If you did it this way you get A,B and C - Nick ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329739 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=11502.10531.4
Re: More Efficient (Faster) Method
*Here are my two cents:* *On the subject of Premature Optimization: I agree with Dave that as developers, sometimes our tendency to create clever code could result in cryptic code, albeit short. That said, I also believe there are definite lines between decent and sloppy code. For example, I was working on a legacy application recently and there were lines of code like cfif a is not and a is not and a is not . (What it meant to say is cfif LEN(TRIM(a)) ). So, the real question is--when is it best to optimize? Personally, my rule of thumb has been do not reinvent the wheel. If there is a native CF function or tag that can be used to get your idea across, then by all means use it. That is probably an overly simplified view, but it is a start. * *On the subject of using the database to store calculated date values: Assuming the shipping date calculation is the only one you would be doing on a regular bases for this application, I think it is a bit of an overkill. However, there are situations when doing that is a good idea. For example, I used to work for a company with an application that processes payroll-related data. As such, it constantly needs to refer to X business days before or after current date. * *Now, on a microscopic level: * When I suggested the UDF BusinessDaysAdd(), I had meant it for that block of code to set the NewDay value, which does not include Saturday as the new day (delivery date). So you could rewrite it as: cfset variables.newDay = BusinessDaysAdd(NOW(),2) As for the loops... Is the inner loop for query qryGetShipCosts really necessary? For each shopping cart, your query should retrieve only one row from the database--one shipping cost for each delivery date option, correct? If so, get rid of that loop and just refer to #qryGetShipCosts.NextDay# and etc, like the following: cfloop from=1 to=30 index=i cfif DayOfWeek(variables.newDay) NEQ 1 li#LSDateFormat(variables.newDay, mmm-dd-)# - #DayOfWeekAsString(DayOfWeek(variables.newDay))# !---Next Day Delivery --- cfif i EQ 1 strong#qryGetShipCosts.NextDay#/strong !---Two Day Delivery --- cfelseif i EQ 2 strong#qryGetShipCosts.TwoDay#/strong !--- All other delivery options get standard price unless it is for a Saturday. --- cfelse cfif DayOfWeek(variables.newDay) NEQ 7 #qryGetShipCosts.Standard# cfelse #qryGetShipCosts.Saturday# /cfif /cfif /li /cfif cfset variables.newDay = DateAdd(d,1,variables.newDay) /cfloop *Finally, a couple of personal habits if I may be so indulged to go on...* *I always include SELECT TOP 1... in a query if I expect that query to return one and only one row. I think it makes it clearer to the reader what is to come. * *I have an obsessive compulsion to scope ALL of my variables. I think it makes your code far more readable and easier to maintain. In your code for example, if the reader sees the line of code cfset newDay = ... they will probably guess NewDay is a local variable. However, it is still nice to explicitly scope NewDay everywhere so wherever the reader's eyes land first, he/she knows it is a local variable. I know the CF books tell you *sometimes* it is a good idea not to scope variables because it makes your code more flexible. There are certainly situations where that is true. For example, maybe you have a page that expects a product_id to display a certain product, and this product_id could come either in FORM or URL scopes. However, I am not convinced this flexibility is worth it at the cost of readability. You could always cast your URL scopes in FORM scope either by way of some JavaScript or through settings in a framework like Fusebox. * Just a few thoughts... [?] ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329740 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: More Efficient (Faster) Method
On Sun, Jan 17, 2010 at 11:44 AM, Eric Nicholas Sweeney n...@bigfatdesigns.com wrote: I would also add - that this probably doesn't exactly fall into the Premature category. The code is completed and it works. Now am I wondering the different ways it could or should be improved upon... improved upon is pretty broad. If you criteria is maintainability, you may refactor in a different direction to performance - sometimes they trade off against each other. So the question is: is it fast enough? If the answer is yes, performance is not an issue. If the answer is yes, profile it (and timing code to see where the bottlenecks are) and refactor for performance. If it is fast enough, the question is: can you maintain it? Do you find the suggested alternatives easier from a maintenance point of view or not? The fastest code is not always the easiest to maintain - and may vary between different versions of CF as well. That's why premature optimization is being bandied around as a concern here... -- Sean A Corfield -- (904) 302-SEAN Railo Technologies US -- http://getrailo.com/ An Architect's View -- http://corfield.org/ If you're not annoying somebody, you're not really alive. -- Margaret Atwoo ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329741 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: More Efficient (Faster) Method
There has already been some pretty good advice on approach and optimization. Assuming the shipping date calculation is the only one you would be doing on a regular bases for this application, I think it is a bit of an overkill. However, there are situations when doing that is a good idea. Yes, I would agree this definitely falls into the realm of it depends. But for some reason I keep wondering if there is not a little more involved here .. Either way, it is still good to consider some of the options. Two factors I generally consider when handling dates are flexibility and maintainability. While there are typically base rules like business days, most applications also have to deal with exceptions to those rules, like holidays. That is when can often make more sense to use a calendar table. Exceptions like those are usually easier to maintain in database table, rather than trying to do the equivalent in CF code. It is certainly possible, but it is not always easy to maintain. Also given the availability of information, many applications quickly grow into the need for reporting as well. For example, how many orders were placed, what were the average orders in a given date period (including days with no sales), etcetera. There again it is often easier to use a calendar table for those tasks. As code based alternatives can be much more cumbersome in certain situations. Having said that, not every application needs that much flexibility. If you simply need to display the days of the month, a calendar table probably is not needed. But given some of the rules you mentioned, I suspect there may be a little more involved here, in which case your application _might_ benefit from this kind of flexibity. Either way, it is good to think broadly and consider what features your application may need and how easy it would be to achieve and maintain them with approach A versus B. So you can make an informed decision about the best approach for your application overall, with regards to flexibility, maintainence and performance. -Leigh ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329742 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: ORM question
If you subCategories collections are relatively small, then you should be safe to just loop over it and terminate after the third row. Yeah, you'll be getting more than you need back from the database, but Hibernate is really good about optimizing data access for relationships, so I'd assume it WON'T be a problem until you demonstrate via load testing that it is. No question, ORM is quite a departure from the normal SQL world. It can be hard to get into, but it's worth giving it a try. Really. The payoffs in the maintenance phase are huge, because you're expression your code at a much higher level than with SQL. cheers, barneyb On Sun, Jan 17, 2010 at 10:44 AM, Victor Moore victor.mo...@gmail.com wrote: Hi Barney, After trying to find the answer to the question for almost a day I was afraid that the answer is no but just wanted to be sure :) The reason I want only a few is for display purposes. Just to give some indication to users the type of subcategories exists. While I like the idea of ORM, I'm afraid to use it in a heavy production environment because I don't really know the guts of it and may introduce problems that are hard to debug. I'm starting a new project and I'm on the fence. I'm just learning it and don't want to jeopardize it because my inexperience (with ORM) plus (at least initially) will take me more time to code than using direct SQL, I know SQL, it comes very easy to work with and (for the most part) I understand, can optimize and test it. Thanks Victor On Sat, Jan 16, 2010 at 11:58 PM, Barney Boisvert bboisv...@gmail.com wrote: The short answer is no. The long answer is that yeah, you can do a whole bunch of hacking around to make it work like that (or at least APPEAR to work like that), but it's a mess. I can't think of a case when you wouldn't be better off a) just constraining the loop over the subcategories when you go to use them, or b) using a separate query for subcategoies rather than a relationship traversal. What's your reason for wanting to only get three? cheers, barneyb On Sat, Jan 16, 2010 at 8:49 PM, Victor Moore victor.mo...@gmail.com wrote: Hi, I have the following cfc: component output=false persistent=true entityname=Category table=category { property name=catID column=cat_id; property name=name ; property name=subCategories fieldtype=one-to-many cfc=SubCategory singularname=SubCategory fkcolumn=cat_id cascade=all lazy=extra; } is it possible to retrieve only 3 subCategories when calling entityLoad (Category)? Thanks Victor ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329743 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: ORM question
According to this posty, http://www.rupeshk.org/blog/index.php/2009/09/coldfusion-orm-performance-tuning-lazy-loading/, if you use lazy=proxy, you would only load the objects you use. So if you only displayed the first three, then only the first three would be loaded. On Sun, Jan 17, 2010 at 7:13 PM, Barney Boisvert bboisv...@gmail.com wrote: If you subCategories collections are relatively small, then you should be safe to just loop over it and terminate after the third row. Yeah, you'll be getting more than you need back from the database, but Hibernate is really good about optimizing data access for relationships, so I'd assume it WON'T be a problem until you demonstrate via load testing that it is. No question, ORM is quite a departure from the normal SQL world. It can be hard to get into, but it's worth giving it a try. Really. The payoffs in the maintenance phase are huge, because you're expression your code at a much higher level than with SQL. cheers, barneyb On Sun, Jan 17, 2010 at 10:44 AM, Victor Moore victor.mo...@gmail.com wrote: Hi Barney, ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329744 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: ORM question
lazy=proxy gives you N+1 behaviour for your collection. That is, if you need a Category and it's 10 subcategories, you'll end up doing 11 queries (one to retrieve each row individually). Of course, if you only use the category and three children you'll only run 4 queries. But if you do an eager fetch of the subcategories (the default), you'll run a single query. Period. Yes, it'll be wider, but it's a single query and therefore avoids a significant amount of overhead. I've done a number of projects with Hibernate, and if I've learned anything, it's that second guessing Hibernate is usually the wrong thing to do. I don't know where those guys learned how to do their jobs, but they are DAMN good at it. cheers, barneyb On Sun, Jan 17, 2010 at 7:23 PM, Raymond Camden rcam...@gmail.com wrote: According to this posty, http://www.rupeshk.org/blog/index.php/2009/09/coldfusion-orm-performance-tuning-lazy-loading/, if you use lazy=proxy, you would only load the objects you use. So if you only displayed the first three, then only the first three would be loaded. On Sun, Jan 17, 2010 at 7:13 PM, Barney Boisvert bboisv...@gmail.com wrote: If you subCategories collections are relatively small, then you should be safe to just loop over it and terminate after the third row. Yeah, you'll be getting more than you need back from the database, but Hibernate is really good about optimizing data access for relationships, so I'd assume it WON'T be a problem until you demonstrate via load testing that it is. No question, ORM is quite a departure from the normal SQL world. It can be hard to get into, but it's worth giving it a try. Really. The payoffs in the maintenance phase are huge, because you're expression your code at a much higher level than with SQL. cheers, barneyb On Sun, Jan 17, 2010 at 10:44 AM, Victor Moore victor.mo...@gmail.com wrote: Hi Barney, ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329745 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: ORM question
I'm confused - are you saying this _doesn't_ solve the problem - or has side effects if he doesn't use it as described? Or are you saying that it is best to just get em all at once? On Sun, Jan 17, 2010 at 10:19 PM, Barney Boisvert bboisv...@gmail.com wrote: lazy=proxy gives you N+1 behaviour for your collection. That is, if you need a Category and it's 10 subcategories, you'll end up doing 11 queries (one to retrieve each row individually). Of course, if you only use the category and three children you'll only run 4 queries. But if you do an eager fetch of the subcategories (the default), you'll run a single query. Period. Yes, it'll be wider, but it's a single query and therefore avoids a significant amount of overhead ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329746 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4
Re: ORM question
It does solve the problem, but has pretty significant performance implications in common use cases, which is why it's not the default. Obviously it's hard to say what is best without seeing the code, but I'd say the default (just get them all) is probably best, unless the category tree is really broad. Fetching a bit more data than you need with a single query is usually better than fetching exactly the right amount of data at really fine granularity with a lot of little queries. The connection/query overhead is more expensive than the return data transfer. Ideally you'd get both (exact right data in a single query), however since you use your objects in lots of different ways but only get to map them once, you have to generalize a bit. Or you can make everything lazy and do all ops with HQL, which would be as perfect as SQL, but with all the downsides and more, so don't do that. :) Sorry for how run-on that is. Hard to do editing on the phone, so I just kind of streamed it out. cheers, barneyb -- Barney Boisvert bboisv...@gmail.com http://www.barneyb.com/ On Jan 17, 2010, at 9:52 PM, Raymond Camden rcam...@gmail.com wrote: I'm confused - are you saying this _doesn't_ solve the problem - or has side effects if he doesn't use it as described? Or are you saying that it is best to just get em all at once? On Sun, Jan 17, 2010 at 10:19 PM, Barney Boisvert bboisv...@gmail.com wrote: lazy=proxy gives you N+1 behaviour for your collection. That is, if you need a Category and it's 10 subcategories, you'll end up doing 11 queries (one to retrieve each row individually). Of course, if you only use the category and three children you'll only run 4 queries. But if you do an eager fetch of the subcategories (the default), you'll run a single query. Period. Yes, it'll be wider, but it's a single query and therefore avoids a significant amount of overhead ~| Want to reach the ColdFusion community with something they want? Let them know on the House of Fusion mailing lists Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:329747 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4