QueryDSL: Query by composite primary key - java

I have an entity Parte with a composite primary key. These are the columns:
codabast
codejerc
codparte
I have annotated my entity with #IdClass(PartePK.class). Now, to perform a query by primary key, I do this:
JPAQuery query = new JPAQuery(entityManager);
query.from(qParte).where(qParte.codabast.eq(myCodAbast)
.and(qParte.codejerc.eq(myCodEjerc)
.and(qParte.codparte.eq(myCodParte))));
Parte p = query.singleResult(qParte);
Is it needed to do it field by field? Or does exist a way to query by primary key?
I would like something like this:
PartePK primaryKey = new PartePK(3, 4, 6);
query.from(qParte).byId(primaryKey);
Thanks in advance.

Related

How can i insert or update jpa entity based on non unique key?

I have a Mysql table like below :
CREATE TABLE ABCD
(
TId BIGINT(8) PRIMARY KEY AUTO_INCREMENT,
TKey VARCHAR(200) NOT NULL,
TValue BIGINT(8) NOT NULL
);
it has data like below :
TId TKey TValue
1 abc 123
2 cde 345
3 def 546
What i want to do is , if i again insert entity with same TKey it'll update existing record instead of inserting new one.
Below is my code to save entity :
ABCD abcd = new ABCD();
abcd.setKey(key);
abcd.setValue(value);
abcdService.create(abcd);
Hibernate keeps tracks of entities in your Java code using the primary key column value. So, if you create a new ABCD entity with the key cde and some value, Hibernate will this as a new entity, and when you save it will result in an insert into your underlying table.
If you want to instead modify the entity whose key is cde, then you should first fetch that record:
EntityManager em = getEntityManager();
ABCD movie = em.find(ABCD.class, 2);
movie.setValue(789);
The above assumes that your framework already handles transactions for you.

JPA - Retrieving data from database table wrt Foreign key -

I am trying to retrieve data from a table which has a foreign key, "reg_no". And the foreign key is not unique, it can be duplicated.
Now I want to retrieve the data from this table using this foreign key. I will provide a "reg_no" and the Java Persistence API will retrieve a list of the result set from the table wrt to "reg_no" provided.
Please enlighten me how can I solve this problem?
You can do something like this, using JPQL:
String queryString = "SELECT t FROM YourTable t " +
"WHERE reg_no = :regNo";
Query query = getEntityManager().createQuery(queryString);
query.setParameter("regNo", regNoValue);
return query.getResultList();
EntityManager entityManager = entityManagerFactory.createEntityManager();
List results = em.createQuery("SELECT c FROM Vehicle v WHERE reg_no = :reg_no").setParameter("reg_no", new String("0000")).getResultList;

Hector - Insert row with composite key

Hi I want to insert into this kind of column family row with composite key:
CREATE TABLE my_items (
user_id uuid,
item_id uuid,
description varchar,
PRIMARY KEY (user_id, item_id));
So I try this:
StringSerializer stringSerializer = StringSerializer.get();
UUIDSerializer uuidSerializer = UUIDSerializer.get();
CompositeSerializer compositeSerializer = CompositeSerializer.get();
HColumn<String, UUID> hColumnObj_userID = HFactory.createColumn("user_id", userID, stringSerializer, uuidSerializer);
HColumn<String, UUID> hColumnObj_itemID= HFactory.createColumn("item_id", itemID, stringSerializer, uuidSerializer);
Mutator<Composite> mutator = HFactory.createMutator(
repository.getKeyspace(),
compositeSerializer);
Composite colKey = new Composite();
colKey.addComponent(userID, uuidSerializer);
colKey.addComponent(itemID, uuidSerializer);
mutator.addInsertion(colKey,
"my_items", hColumnObj_userID);
mutator.addInsertion(colKey,
"my_items", hColumnObj_itemID);
mutator.execute();
What's wrong with code above? I keep getting this error: "InvalidRequestException(why:UUIDs must be exactly 16 bytes)". And how can I insert data into column family that I describe above.
Cheers
It looks like Hector was expecting a Composite containing a UUID and a String and found only a string.
Before writing the Hector code you have to translate the create DDL into the actual storage pattern CQL uses. In this case, even though you have two primary keys, only the first, user_id, is used as the row key. That's always the case. Any other primary keys (item_id in this case) are used to form composite column names for every column except the first primary key. That means that when using Hector for your my_items column family you'll have to write two columns, one for item_ID and one for description.
The column name for the item_id value is a composite consisting of the values of primary keys 2...n (item_id in this example) and a constant string name of the value ("item_id").
The column name for the description value is also a composite of the item_id value and the name of the value ("description").
If you wrote 3 CQL table rows, each with the same user_id but having different item_id values then you'd end up with a single column family row whose row key is the common user_id value and which has 6 columns, an item_id column and a description column for each of the 3 CQL table rows.
The code should look like this:
import java.util.UUID;
import me.prettyprint.cassandra.serializers.CompositeSerializer;
import me.prettyprint.cassandra.serializers.IntegerSerializer;
import me.prettyprint.cassandra.serializers.StringSerializer;
import me.prettyprint.cassandra.serializers.UUIDSerializer;
import me.prettyprint.hector.api.Keyspace;
import me.prettyprint.hector.api.beans.Composite;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
// put this here to make it compile cleanly
Keyspace keyspace = null;
UUID userID = null;
UUID itemID = null;
String description = null;
// Row key is user_id of type UUID
Mutator<UUID> mutator = HFactory.createMutator(
keyspace,
UUIDSerializer.get());
// write column for itemID.
// Column name is composite of itemID value and constant "item_id"
// Row key is value of userID
Composite itemIdColumnName = new Composite();
itemIdColumnName.addComponent(itemID , UUIDSerializer.get());
itemIdColumnName.addComponent("item_id" , StringSerializer.get());
// HFactory.createColumn takes args: column name, column value, serializer for column name, serializer for column value
HColumn<Composite, UUID> hColumnObj_itemID = HFactory.createColumn(itemIdColumnName, userID, new CompositeSerializer(), UUIDSerializer.get());
mutator.addInsertion(userID, "my_items", hColumnObj_itemID);
// write column for description.
// Column name is composite of itemID value and constant "description"
// Row key is value of userID
Composite descriptionColumnName = new Composite();
itemIdColumnName.addComponent(itemID , UUIDSerializer.get());
itemIdColumnName.addComponent("description" , StringSerializer.get());
HColumn<Composite, String> hColumnObj_description = HFactory.createColumn(descriptionColumnName, description , new CompositeSerializer(), StringSerializer.get());
mutator.addInsertion(userID, "my_items", hColumnObj_description);
mutator.execute();

Hibernate, search by primary key returns all from table

I have this issue with Hibernate that when i try to retrieve unique result using criteria hibernate returns all the content from the table.
Session session = HibernateUtil.beginTransaction();
Customer c = new Customer();
c.setCustId(custId);
Example ex = Example.create(c);
Criteria criteria = HibernateUtil.getSession().createCriteria(Customer.class);
criteria.add(ex);
Customer customer = (Customer)criteria.uniqueResult();
HibernateUtil.commitTransaction();
HibernateUtil.closeSession();
However querying the table with:
Customer customer = (Customer)session
.createSQLQuery("select * from customer_ where custid = :id")
.addEntity(Customer.class)
.setInteger("id", custId)
.uniqueResult();
returns correct entry.
custId is the table's primary key. And the Customer class contains 2 #OneToMany mappings.
Do I need to add something to the criteria example above??
The documentation says:
Version properties, identifiers and associations are ignored.
(emphasis mine)
Why not simply using Session.get() if you have the identifier?

How to get super table information in java?

My database had a lot of parent and child tables.The tables contains the foreign key which has the link with the parent table.I wants to get the information of parent table of the child table using java?How can I achieve that?
For ex,consider the student and mark table,
The student table contains the information like studentID,name.
studentID-Primary key
The marks table contains the markId,studentId,Sub1,sub2,sub3 etc
markId-Primarykey
studentID-Foreignkey refers Student table
My table creation queries are,
CREATE TABLE `Student12` (
`studentId` SMALLINT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`studentId`)
)
ENGINE = InnoDB;
CREATE TABLE `Marks` (
`markId` SMALLINT NOT NULL AUTO_INCREMENT,
`subject1` SMALLINT NOT NULL,
`subject2` SMALLINT NOT NULL,
`studentId` SMALLINT NOT NULL,
PRIMARY KEY (`markId`),
CONSTRAINT `FK_Marks_Student` FOREIGN KEY `FK_Marks_Student` (`studentId`)
REFERENCES `Student12` (`studentId`)
ON DELETE RESTRICT
ON UPDATE RESTRICT
)
ENGINE = InnoDB;
If I give the mark table name as input, how can I get its parent or super table name student and information about student table?Any help should be appreciable.
It totally depends on the way tables are created. Foreign keys are not mandatory to create, they could be a simple column in one table with no explicit relationship to the other table. If you are very sure that the links are created explicitly (the foreign keys are defined) then you could use information_schema. But if there is no foreign key defined (which is true in most of the databases I have seen), then there is no way for you to find the links inside the database. You have to look into the code (if there is any available) and try to find a clue.
The JDBC DatasetMetaData interface provides a couple of methods that may help. (The following text is copied from the javadoc.
ResultSet getExportedKeys(String catalog, String schema, String table)
Retrieves a description of the foreign key columns that reference the given table's primary key columns (the foreign keys exported by a table).
ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable)
Retrieves a description of the foreign key columns in the given foreign key table that reference the primary key or the columns representing a unique constraint of the parent table (could be the same or a different table).
Of course, these can only work if the relevant columns have been declared as foreign keys in the SQL table DDL.
You can use the DatabaseMetaData to retrieve informations about foreign keyes
and the referenced Tables. Im not sure if it works with all kinds of MySql Tables.
The principle is to use the follwing code (not tested) to retrieve information about the super tables
ResultSet rs = null;
DatabaseMetaData dm = conn.getMetaData( );
// get super tables of table marks
ResultSet rs = dm.getSuperTables( null , null, "marks" );
while( rs.next( ) ) {
System.out.println(String.format("Table Catalog %s", rs.getString("TABLE_CAT") );
System.out.println(String.format("Table Schema %s", rs.getString("TABLE_SCHEM") );
System.out.println(String.format("Table Name %s", rs.getString("TABLE_NAME") );
System.out.println(String.format("Table Name %s", rs.getString("SUPERTABLE_NAME") );
}
You can use thes informations to get additional informations about the referenced table
and the foreigen and referenced primary keys:
ResultSet rs = dm.getCrossReference( null , null , "student" , null , null , "marks" );
System.out.println(String.format("Exported Keys Info Table %s.", "marks"));
while( rs.next( ) ) {
String pkey = rs.getString("PKCOLUMN_NAME");
String ptab = rs.getString("PKTABLE_NAME");
String fkey = rs.getString("FKCOLUMN_NAME");
String ftab = rs.getString("FKTABLE_NAME");
System.out.println("primary key table = " + ptab);
System.out.println("primary key = " + pkey);
System.out.println("foreign key table = " + ftab);
System.out.println("foreign key = " + fkey);
}
And finally you can retrieve the information about the super table by
ResultSet rs = dm.getTables(null,null,"student" ,null);
System.out.println("Table name:");
while (rs.next()){
String table = rs.getString("TABLE_NAME");
System.out.println(table);
}

Categories