Spring jdbc repository many-to-many conjunction table column names - spring-data-jdbc

I can't find where to define custom column name for conjunction table in case of many-to-many relationship in spring-data-jdbc.
I extended aggregate example from https://github.com/spring-projects/spring-data-examples in my fork: https://github.com/konstiak/spring-data-examples/commit/2a901bb4d81c35406da393b1368109136ae21f5f.
If the conjuction table has columns [color, lego_set] it works out of box. But I'd like to have custom names for these columns [color_id, lego_set_id]. It's clear for 'color_id'. I can define it by #Column annotation in ColorRef entity. But how can I define that column for LegoSet.id will be stored in 'lego_set_id'?
RESOLVED
I just had to define #Column(value = "lego_set_id") on colors field in LegoSet entity.

Defining #Column(value = "lego_set_id") on colors field in LegoSet entity resolved the problem.

Related

How to specify ignore case in JPA #JoinColumn when I am using two tables entity

I have two entities. Account entity and B_Account.
In Account entity I am joining table like below.
#ManyToOne(fetch=eger)
#JoinColumn(name = "a_type")
private B_Account b_Account;
Now the issue is a_type attribute value in Account is "ganesh" and in B_Account is "GANESH".
This is the reason I am not getting the data when I used findBy(B_Account) using repository method.
How can I join the tables above so that it can ignore the small and uppercase?
You can try #JoinFormula That's a Hibernate proprietary annotation that doesn't exist in JPA.
#ManyToOne(fetch=eger)
#JoinFormula(name = "lower(b_account) = a_type")
private B_Account b_Account;
I cannot test it so please try it out.
Documentation: https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#associations-JoinFormula

#SecondaryTable with where condition

I am creating entity for table created outside of my system. I want to bind data from other table to entity field by using #SecondaryTable (or possibly better solution), but only to do so if condition is met. IE. my table has 1 row, I want to bind data from other table (oneToMany) where certain condition is met (exactly one match from other table(transform to one to one)). Can I use #Where annotation and how? If not is there alternative?
Edit: here is the entity and additional info on the related table
#Entity
#Table(name = "RE_STORAGE_INSTANCE")
public class Movie {
#Id
#Column(name="ID_")
private Long id;
...
//Column I want to fetch
private Date dueDate;
}
Table RE_VARIABLES manyToOne to table RE_STORAGE_INSTANCE, contains fields: re_key, re_value. I want to fetch re_value only if 're_key' equals dueDate. Even though it's manyToOne, only one row of RE_VARIABLES contains due date for each RE_STORAGE_INSTANCE row.

JSF datatable columns from multiple database tables

I have a JSF datatable, it has three columns, those are:Work_Type_Desc, Project_Phase, and Activity_Desc. Those columns comes from 2 different database tables, the relationship of those two tables are one-to-many.
The 1st Table name is Work_Type. It has 1) Work_Type_Cd, 2)Work_Type_Desc, 3)Created_By_Name, 4)Created_DT, 5)Updated_By_Name, 6) Updated_DT
The 2nd Table name is Activity_Type. It has 1)Activity_Cd,2) Work_Type_Cd,3)Project_Phase,4)Activity_Desc, 5)Created_By_Name, 6)Created_DT, 7)Updated_By_Name, 8) Updated_DT.
I use Hibernate+Spring+JSF, my question is how to show those three column records in JSF datatable, do I need to create a new model domain class to store this two tables properties? If so, how to handle the PK and FK in the new model class. Thanks!
Just let your service layer return a List<ActivityType>. The WorkType is already referenced by #ManyToOne property in ActivityType, right?
<h:dataTable value="#{bean.activityTypes}" var="activityType">
<h:column>#{activityType.workType.workTypeDesc}</h:column>
<h:column>#{activityType.projectPhase}</h:column>
<h:column>#{activityType.activityDesc}</h:column>
</h:dataTable>
It's generally unnecessary to create another mapping layer for that.

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;

Retrieving rows based on a certain criteria regarding a many-to-many mapping in Hibernate

I'm just copy & pasting some of the introductory text from one of my questions, since the same table relationship is involved in this question also.
I have three of many tables in Oracle (10g) database as listed below. I'm using Hibernate Tools 3.2.1.GA with Spring version 3.0.2.
Product - parent table
Colour - parent table
ProductColour - join table - references colourId and prodId of Colour and Product tables respectively
Where the table ProductColour is a join table between Product and Colour. As the table names imply, there is a many-to-many relationship between Product and Colour which is mapped by PrductColour. I think, the relationship in the database can easily be imagined and is clear with only this much information. Therefore, I'm not going to explore this relationship at length unnecessarily.
An entity (row) in Product is associated with any number entities in Colour and an entity (row) in Colour can also be associated with any number of entities in Product.
Since, it is a many-to-many relationship, it is mapped in the Product and the Colour entity classes (POJOs) with their respective java.util.Set and no direct POJO class for the product_colour table is available.
The class Product looks like the following.
public class Product implements java.io.Serializable
{
private BigDecimal prodId;
private Set<Colour> colours = new HashSet<Colour>(0);
.
.
.
//Other properties with setters and getters.
}
The class Colour looks like the following.
public class Colour implements java.io.Serializable
{
private BigDecimal colourId;
private Set<Product> products = new HashSet<Product>(0);
.
.
.
//Other properties with setters and getters.
}
The actual mapping between entities is available in xxx.hbm.xml files, regarding this question which is unnecessary, I think .
What I want to do is to retrieve only those rows from the Colour table which don't match the colour rows in the ProductColour table for a particular product at a time. In this regard, the native Oracle SQL statement would look something like the following.
SELECT colour_id, colour_name, colour_hex
FROM colour
WHERE colour_id not in (SELECT colour_id FROM product_colour WHERE prod_id=81)
ORDER BY colour_id DESC
Where prod_id can be any valid BigDecimal number in Java which is dynamic.
As noted earlier, the relationship is available as a many-to-many relationship in Hibernate, no POJO class for the database table product_colour is available and therefore, I'm fumbling in writing such an HQL statement in Hibernate. I have tried to write such an HQL statement but no attempts were succeeded.
[The code presented in the rest of the part may completely be unnecessary to review]
I'm therefore following a traditional way. What I'm doing is... I'm first retrieving a single product row from the Product the entity class based on a dynamic value of prodId such as,
List<Product>list=session.createQuery("from Product where prodId=:prodId")
.setParameter("prodId", prodId).list();
and then using a loop, I'm getting the entire Colour set - java.util.Set corresponding to the product_colour table in Oracle which is available in the Product entity for this product such as,
Set<Colour>colours=new HashSet<Colour>(0);
for(Product p:list)
{
if(p!=null)
{
colours=p.getColours();
}
}
As can be seen, the colours Set is being populated with all of the colour rows available (reference rows) in the product_colour table in Oracle.
After getting all of these rows, I'm getting the entire Colour entity class itself (all the row in it) that corresponds to the colour table in Oracle and then removing those rows which match the rows retrieved from the product_colour Oracle table (available in the colours Set in the preceding snippet) satisfying the condition as mentioned earlier such as,
List<Colour>colourList=session.createQuery("from Colour order by colourId desc").list();
Iterator<Colour>it=colourList.iterator();
while(it.hasNext())
{
Colour c=(Colour)it.next();
for(Colour pc:colours) //colours is available in the preceding snippet.
{
if(c==pc)
{
it.remove();
}
}
}
This can do what is intended but doing so, may imply some overhead on the system. Additionally, what I want to achieve doesn't seem possible with this approach which is pagination. I can't use the setFirstResult(int) and the setMaxResults(int) methods to accomplish the task of pagination which is the case otherwise like the one shown below regarding the Product entity class,
List<Product> products=session.createQuery("from product order by prodId desc")
.setMaxResults(0).setFirstResult(4);
So the question is again, regarding this relationship, is this possible to write such an HQL statement that can retrieve only those rows from the Colour entity class which don't match the colour rows in the product_colour Oracle table like the native SQL statement shown above?
How can I achieve the concept of pagination otherwise (in case, it is not possible)?
Short answer to a veeeeery long question:
select colour from Colour colour
where colour.id not in (
select colour2.id from Product product
inner join product.colours colour2
where product.id = :productId)

Resources