#Relation Room DB with multiple columns - android-sqlite

If i want to related 2 tables and the relation is not only one column but more, is there a way to use the Room #Relation annotation with more arguments to achive that? Perhaps somehting like below
#Relation(parentColumn = "{message_id,account_id}", entityColumn = "{message_id, from_account_id}", entity = Message::class)
var messageList: List<Message> = ArrayList()
So that the join has more than one constraint?

Related

create a model odoo12 with intermediate tables

I'm starting to learn Odoo and I'm developing an application in Odoo 12. I want to represent a database with intermediate table, in this case I have 2 tables ( products and actions ) and the relationship is 1...n and I must have an intermediate table that joins two tables.
Product (id, name, price...)
Action (id, name)
Product_action (id, id_product, id_action, date_from, date_to)
How I can do this? How can i represent this in the Odoo's model?
Thanks in advance.
Just create a model for the intermediate. You can also represent the entries of this intermediate model (rows in table) as 1:n relation on both the other models:
class ProductAction(models.Model):
_name = "product.action"
date_from = fields.Date()
date_to = fields.Date()
product_id = fields.Many2one(comodel_name="product.product")
action_id = fields.Many2one(comodel_name="action.model.name")
class ProductProduct(models.Model):
_inherit = "product.product"
intermediate_ids = fields.One2many(
comodel_name="product.action", inverse_name="product_id")
class ActionClassName(models.Model):
_inherit = "action.model.name"
intermediate_ids = fields.One2many(
comodel_name="product.action", inverse_name="action_id")
I assumed you are using Odoo's product class product.product but don't know what class/model is used for "actions" so i used a wildcard name for it in my example code.

JPA query using named parameter from a oneToOne joined table

I am trying to create a query that references fields in the WHERE from both the current table and a table joined on a column. I have no problems creating a query from a single parameter in the Participation table.
#NamedQuery(name="Participation.byUserID", query="SELECT c FROM Participation c WHERE c.userID = :userID")
Here is the fun part... Within the Participation entity, I have a join:
#OneToOne(optional=false)
#JoinColumn(name = "EventID", insertable = false, updatable = false)
private Event event;
The Event entity has some fields I would like to use in my query. For example, eventDate or eventType.
I am wanting something like WHERE Participation.userID = 123 AND Event.eventType = "meeting" using JPA queries instead of SQL. How can I expand the simple named query above to include comparisons from the joined table?
So far I have not been able to get this working, so any help would be appreciated.
This is a really simple requirement, I suggest you go through some basic JPA tutorials.
SELECT c FROM Participation c WHERE c.userID = :userID and c.event.eventType = :eventType

Join Two table in Criteria Query

I have three tables one is ItemCategory,ItemMaster and Price. I am referring itemaCategoryId in ItemMaster table and like that referring itemmasterid in price. Now i have to display contents of price order by itemcategory id. This is my criteria query.
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Price> cq = cb.createQuery(Price.class);
Root<Price> root = cq.from(Price.class);
Root<ItemMaster> itemMasterRoot = cq.from(ItemMaster.class);
Root<ItemCategory> itemCategoryRoot = cq.from(ItemCategory.class);
Join<ItemMaster, ItemCategory> s=itemMasterRoot.join(ItemMaster_.category);
Join<Price,ItemMaster> y=root.join(Price_.itemMaster);
Path<Long> itemMasterId=root.get(Price_.itemMasterId);
cq.select(root).where(cb.equal(root.get(Price_.priceMasterId), priceMasterId))
.orderBy(cb.asc(itemMasterId));
TypedQuery<Price> q = entityManager.createQuery(cq);
Above my criteria Query
If you use multiple from statements, you get the cartesian product of all entities. If you want to preserve the relationships, use join instead:
Root<Price> price = cq.from(Price.class);
Join<Price,ItemMaster> itemMaster = price.join(Price_.itemMaster);
Join<ItemMaster, ItemCategory> itemCategory = itemMaster.join(ItemMaster_.category);
However it looks like at least the second join may be useless, because you are able to access the category property directly using the getter, isn't it?:
Price aPriceResult;
ItemCategory categoryResult = aPriceResult.getItemMaster().getCategory();

Zend select data from multiple table

I have trouble with pulling data from two different tables. I'm attempting to first grab all the addresses with a given name (select all the addresses with the name tom in table). Then with the addresses, look through another table (table2) for those addresses and pull a all the data from col number. Is there a better way than my code:
CONTROLLER:
this->table = new Address();
$getaddress = $this->table->getAddress($name); //grabbing all address associated with a given name
$address = $getaddress->toArray();
foreach ($addy as $address)
{
this->table2 = new Number();
$numbers = $this->table2->getNumber($address['numberColumn']);
$this->view->numbers = $numbers->toArray();
}
I will advice you to define relationship between table and table2. Of course you need foreign key in table2 which will be the relation to the first table.
Please study this document:
http://framework.zend.com/manual/1.12/en/zend.db.table.relationships.html

SqlResultSetMapping with self join table

I have a query with a self join that looks like this,
select t1., t2. from table t1
left outer join table t2 on t2.LFT < t1.LFT
and t2.RGT > t1.RGT
AND t2.REG_CODE_PAR = 'ALL'
AND t1.STATUS_CODE = 'A'
AND t2.STATUS_CODE = 'A'
I'm using #NamedNativeQuery with a result set mapping to get the result.
#NamedNativeQuery(
name="findTree",
query="..... the query above",
resultSetMapping = "regionT")
With the following result set mapping
#SqlResultSetMapping(name = "regionT" , entities ={
#EntityResult(
entityClass = Tree.class
fields = {
#FieldResult(name = "regCode", column = "REG_CODE")
#FieldResult(name = "rgt", column = "RGT"),
#FieldResult(name = "lft", column = "LFT"),
#FieldResult(name = "name", column = "NAME"),
#FieldResult(name = "regCodePar", column = "REG_CODE_PAR"),
#FieldResult(name = "statusCode", column = "STATUS_CODE")
}
),
#EntityResult(
entityClass = TreeSelf.class
fields = {
#FieldResult(name = "regCode1", column = "REG_CODE")
#FieldResult(name = "rgt1", column = "RGT"),
#FieldResult(name = "lft1", column = "LFT"),
#FieldResult(name = "name1", column = "NAME"),
#FieldResult(name = "regCodePar1", column = "REG_CODE_PAR"),
#FieldResult(name = "statusCode1", column = "STATUS_CODE")
}
)
})
The entity class contains looks like this.
#NamedNativeQuery(...)
#SqlResultSetMapping(...)
#Entity
#Table(name = "table")
public class Tree implements Serializable {
#Id
#Column(name = "REG_CODE")
private String regCode; ... ..getters and setters...}
When I run the query using em.createQuery("findTree"), I get the exact same object in both
the 1st and 2nd elements of the returned object array.
Even if I create a class called TreeSelf that is identical to Tree and use it as the 2nd
EntityResult instead of having 2 EntityResults using the same entityClass, I get the same
result.
Can someone point out what's wrong with the configuration?
Let's see if I understand your question. You're expecting to capture two Tree entities from each native query result row. The first entity should be formed from t1's columns. The second entity should be formed from t2's columns. Contrary to expectation, you actually receive two instances formed from t1. No instances from t2 appear. You made a doppelganger Entity for Tree called TreeSelf while debugging, but TreeSelf is ultimately unnecessary and you want to get rid of it. Stop me if any of that was wrong.
I think the problem is due to ambiguous column names. Each column name in the native query appears twice, once from t1 and once from t2. The result mapper seems to be arbitrarily picking the first occurrence of each ambiguous column name for both Tree entities. I'm surprised that works at all. I would have expected an SQLException complaining about column reference ambiguity.
Also, are you sure you want a left outer join? What if no match is found for a t1 row? It will be paired with all NULL in t2's columns. Then you have a null-valued Tree entity. I think. I don't even know what the result mapper would do in that case. Perhaps you want an inner join?
Consider translating this native query into a JPQL query. (JPA Criteria API is just as well, but I find it more cumbersome for examples.) Here's a JPQL version of the native query:
SELECT t1, t2
FROM Tree t1, Tree t2
WHERE t2.lft < t1.lft AND t2.rgt > t1.rgt AND t2.regCodePar = 'ALL' AND
t1.statusCode = 'A' AND t2.statusCode = 'A'
N.B.: This changes the join semantics to inner instead of left outer.
Here's a sketch of code that could run this query:
EntityManager em = ... // EntityManager by injection, EntityManagerFactory, etc.
String jpql = ... // Like example above
TypedQuery<Object[]> q = em.createQuery(jpql, Object[].class);
for (Object[] oa : q.getResultList()) {
Tree t1 = (Tree)oa[0];
Tree t2 = (Tree)oa[1];
}
In case you are stuck with the native query for whatever reason, here's how you can work around the column name ambiguity. Instead of starting the native query like select t1.*, t2.*, alias each column with AS. The SELECT clause would resemble this:
SELECT t1.REG_CODE AS t1_REG_CODE, t1.RGT AS t1_RGT, (... rest of t1 cols ...),
t2.REG_CODE AS t2_REG_CODE, t2.RGT AS t2_RGT, (... rest of t2 cols ...)
The column attribute in each FieldResult must change accordingly. So the column attributes under the first EntityResult should all start with t1_ and the second's should all start with t2_.
I'd humbly recommend deleting the native query and sql result mapper and using JPA Query Language or Criteria API, if you can find a way.
Update: As confirmed in your comments, a useful answer to your question must preserve left (outer) join semantics. Unfortunately, JPQL and the Criteria API don't support complex left join conditions. There is no way to qualify a JPQL left join with an explicit ON condition.
To my knowledege, the only way to do a left outer join under the spec is by traversing an entity relationship. The JPA implementation then generates an ON condition that tests identity equality. The relevant spec bits are 4.4.5 "Joins" and 4.4.5.2 "Left Outer Joins".
To satisfy this constraint, each Tree you want to left-join to its ultimate parent must have an additional column storing the ultimate parent's id. You might be able to cheat around this constraint in a variety of ways (views?). But the path of least resistance seems to be modifying the native query to use aliased arguments, deleting TreeSelf, and updating the result mapper accordingly. Cleverer solutions welcome, though...