How to get data in ofbiz data model when just had partyID? - datamodel

I'm using ofbiz framework and researching data modeling. But I'm confusing with getting data from an entity when just had partyID.
When I know a partyID, I can query at party table to get Party_type_id. Then, I use this Party_type_id to query at party_type to get type of party, example PERSON or PARTY_GROUP. But then how can I exactly go to PERSON or PARTY_GROUP to get individual information of them ? Because I don't show any relationship between party_type and name of table (PERSON or PARTY_GROUP).

I think viewEntity Can solve your problem.
Add the following view-entity in endityengine.xml.
<view-entity entity-name="PartyInfo"
package-name="org.ofbiz.party"
title="View that combines Person, Paryt and PartyGroup">
<member-entity entity-alias="P" entity-name="Party"/>
<member-entity entity-alias="PG" entity-name="PartyGroup"/>
<member-entity entity-alias="PER" entity-name="Person"/>
<alias entity-alias="P" name="partyId"/>
<alias entity-alias="PG" name="groupName"/>
<alias entity-alias="PER" name="firstName"/>
<alias entity-alias="PER" name="lastName"/>
<alias entity-alias="P" name="partyTypeId"/>
<view-link entity-alias="P" rel-entity-alias="PG" rel-optional="true">
<key-map field-name="partyId"/>
</view-link>
<view-link entity-alias="P" rel-entity-alias="PER" rel-optional="true">
<key-map field-name="partyId"/>
</view-link>
</view-entity>
which will have the party information including firstName,lastName Or GroupName (if PartyType = 'PARTY_GROUP') and PartyTypeId.
EntityCondition partyCondition = EntityCondition.makeCondition(UtilMisc.toList(
EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, prtyId)), EntityOperator.AND);
List<GenericValue> partyDetails = delegator.findByCondition("PartyInfo", partyCondition, null, null);
Note : You cannot query databse using this table 'PartyInfo' ( Incase you are not aware of View entity)

Use the same party_id to query the table 'person' to get the info of the party of the party_type_id=PERSON
SELECT * FROM PERSON pers, PARTY p WHERE p.PARTY_ID=pers.PARTY_ID AND p.party_type_id='PERSON' AND pers.PARTY_ID='your-party-id'
Use the same party_id to query the table 'person' to get the info of the party of the party_type_id=PARTY_GROUP
SELECT * FROM PARTY_GROUP pg, PARTY p WHERE p.PARTY_ID=pg.PARTY_ID AND p.party_type_id='PARTY_GROUP' AND pg.PARTY_ID='your-party-id'

You may also try to navigate to Application>Framework>EntityEngine and check for the reln for any entity that you want. It gives quite a comprehensive info. Much like the foreign key connects.

Related

How to select by fields in preloaded object?

I wonder if it is possible to select by a condition in a preloaded object. For example, I have tables User and Profile (one to one). So I need to get all Users with Profiles where sex is female.
I thought it can be done by something like this:
Preload("UserProfile").Where("user_profile.sex = ?", "female")
But it returns something like:
pq: missing FROM-clause entry for table \"user_profile\"
Preloading doesn't join the tables specified. You need to explicitly join the table in question:
Preload("UserProfile").Joins("LEFT JOIN user_profile ON user.id = user_profile.user_id")
.Where("user_profile.sex = ?", "female")
...Assuming your primary key is called id, and foreign key is called user_id.
I also faced the same issue in a recent project. I found the below solution to work for me.
var users []User
Preload("UserProfile","sex = ?","female").Find(&users)
and then check for
user.profile!=nil
The issue in this approach is it will load all users.
But in your case, it can be another way around.
var profiles []Profile
Preload("User").where("sex = ?","female").Find(&profiles)
I hope this will solve your problem.

Extbase Mapping with non-TYPO3-table

I have too classes and two non-TYPO3-tables. I defined a non-TYPO3-table as a table without uid, pid, etc. columns.
My two classes:
class Tx_Abc_Domain_Model_Location extends Tx_Extbase_DomainObject_AbstractEntity
class Tx_Abc_Domain_Model_Facility extends Tx_Extbase_DomainObject_AbstractEntity
My two tables (with columns):
locations
zipcode
city
facility_id
facilities
facility_id
name
I've mapped the attributes like this:
config.tx_extbase.persistence.classes {
Tx_Abc_Domain_Model_Location.mapping {
tableName = locations
columns {
zipcode.mapOnProperty = zipcode
city.mapOnProperty = city
facility_id.mapOnProperty = facility
}
}
Tx_Abc_Domain_Model_Facility.mapping {
tableName = facilities
columns {
facility_id.mapOnProperty = uid
name.mapOnProperty = name
}
}
}
My problem:
The facility attribute of my location model got the type Tx_Abc_Domain_Model_Facility and when I'm looking for a location via the LocationRepository it builds me a location model which contains a facility model.
The problem appears, when I the search I am doing returns several results. i.e. the location with the zipcode 12345 has two different facilities (and the table locations got two rows with different facility_ids), then I would expect to get two location models and each of it got the right facility model.
But instead I get the two location models, which have all same facility model inside. They've got all the facility of the first found location.
Even if I change the type of the facility attribute to integer, there are the wrong ids. But if I enable raw query result in repository I get the correct ids.
I get also the correct ids or models, when I add to both tables an uid-column.
Is there no possibility to map tables without uid column with Extbase models?
Thanks.
Okay, the answer to my last question is: Yes, there is no possibility to map tables without uid column with Extbase models.
There is an existing ticket on forge: http://forge.typo3.org/issues/25984
The reason seems to be the hardcoded $row['uid'] in mapSingleRow() method in Tx_Extbase_Persistence_Mapper_DataMapper class.
If it's not alot of tables you have to map, a work-around could be to create views for those tables to just map the uid.
I.e.:
CREATE VIEW tx_abc_domain_model_facility AS
SELECT facility_id AS uid, facilities.* FROM facilities;

With the use of Apex code, how can I select all ''OpportunityProducts' objects which are belongs to particular 'Opportunity Id'

I am way to customizing 'Sales' application that belongs to 'salesforce.com' platform.
Is there any way to select all the 'OpportunityProducts' objects which are belongs to particular 'Opportunity Id' ?
[SELECT Id FROM OpportunityProduct WHERE Opportunity =:opportunitId];
When I execute above code for select those 'OpportunityProduct', I got following error. If any one have some idea please update me. Thanks.
Save error: sObject type 'OpportunityProduct' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.
Another way to get this done when you need the actual products, not just the line items, is as follows. First get your opportunities:
List<Opportunity> opps = [SELECT Id, Name FROM Opportunity LIMIT 1000];
Then loop through to create a list of opportunity Ids
List<Id> oppIds = new List<Id>();
for(Opportunity o : opps)
{
oppIds.add(o.Id);
}
Now get your actual products that belong to your opportunities...
List<OpportunityLineItem> oppProds = [SELECT Id, PricebookEntry.Product2.Name, PricebookEntry.Product2.Family
FROM OpportunityLineItem
WHERE OpportunityId IN :oppIds];
Hope that helps.

Table with a foreign key

how can I build a table of "orders" containing "IdOrder", "Description" and "User"?... the "User" field is a reference to the table "Users", which has "IdUser" and "Name". I'm using repositories.
I have this repository:
Repository<Orders> ordersRepo = new OrderRepo<Orders>(unitOfWork.Session);
to return all Orders to View, I just do:
return View(ordersRepo.All());
But this will result in something like:
IdOrder:1 -- Description: SomeTest -- User: UserProxy123ih12i3123ih12i3uh123
-
When the expected result was:
IdOrder:1 -- Description: SomeTest -- User: Thiago.
PS: I don't know why it returns this "UserProxy123ih12i3123ih12i3uh123". In Db there is a valid value.
The View:
It is showed in a foreach (var item in Model).
#item.Description
#item.User //--> If it is #item.User.Name doesn't work.
What I have to do to put the Name on this list? May I have to do a query using LINQ - NHibernate?
Tks.
What type of ORM are you using? You mention "repositories" but does that mean LinqToSql, Entity Framework, NHibernate, or other?
It looks like you are getting an error because the User field is not loaded as part of the original query. This is likely done to reduce the size of the result set by excluding the related fields from the original query for Orders.
There are a couple of options to work around this:
Set up the repository (or context, depending on the ORM) to include the User property in the result set.
Explicitly load the User property before you access it. Note that this would be an additional round-trip to the database and should not be done in a loop.
In cases where you know that you need the User information it would make sense to ensure that this data in returned from the original query. If you are using LinqToSql take a look at the DataLoadOptions type. You can use this type to specify which relationships you want to retrieve with the query:
var options = new DataLoadOptions();
options.LoadWith<Orders>(o => o.User);
DataContext context = ...;
context.LoadOptions = options;
var query = from o in context.Orders
select o;
There should be similar methods to achive the same thing whatever ORM you are using.
In NHibernate you can do the following:
using (ISession session = SessionFactory.OpenSession())
{
var orders = session.Get<Order>(someId);
NHibernateUtil.Initialize(orders.User);
}
This will result in only two database trips (regardless of the number of orders returned). More information on this can be found here.
In asp.net MVC the foreign key doesn't work the way you are using it. I believe you have to set the user to a variable like this:
User user = #item.User;
Or you have to load the reference sometimes. I don't know why this is but in my experience if I put this line before doing something with a foreign key it works
#item.UserReference.load();
Maybe when you access item.User.Name the session is already closed so NHib cannot load appropriate user from the DB.
You can create some model and initialize it with proper values at the controller. Also you can disable lazy loading for Orders.User in your mapping.
But maybe it is an other problem. What do you have when accessing "#item.User.Name" from your View?

SubSonic 3.0 ActiveRecord - Preferred approach building object graph?

Say I have a forum system with Threads, Posts and Tags.
The structure is the same as StackOverflow: Threads have a 1-many relationship to Posts, and Tags have a many-many relationship to Threads.
The (simplified) tables:
Thread
------
ThreadID int PK
Title varchar(200)
Tag
----
TagID int PK
Name varchar(50)
ThreadTag
-----------
ThreadTagID int PK
ThreadID int FK
TagID int FK
So SubSonic ActiveRecord templates generate my classes for me.
Code
For the front page I need to get a list of Threads, and attach to each of these its list of related Tags. Leaving the posts count aside, what is the best way to retrieve the Tags and build this object graph?
If I get the threads like:
var threadQuery = Thread.All().Skip(x).Take(n);
var threadList = threadQuery.ToList();
Should I add an "IList<Tag> Tags" property to a partial of the Thread class?
And to retrieve the right tags, should I execute two queries: one to get the ThreadTags and one to get the Tags themselves: e.g.
var tagLinks = (from t in threadQuery
join l in ThreadTag.All() on t.ThreadID equals l.ThreadID
select l).ToList();
var tags = (from t in threadQuery
join l in ThreadTag.All() on t.ThreadID equals l.ThreadID
join tg in Tag.All() on l.TagID equals tg.TagID
select tg).ToList();
...and then use these lists to sort the tags in to the correct Thread.Tags list?
Is there a better way? I don't think I can use the IQueryable properties generated by SubSonic using the foreign keys, as that would trigger a database call for each of the Threads in my list.
After using SubSonic for a while, I think this is the best way. For large complex object graphs Entity Framework seems better suited.

Resources