Liferay Service Builder - Creating References - java

I am trying to create Relationship between 3 tables. Following are the tables:
rooms
facilities
facilityMapping
rooms table contains
roomId
roomName
facilities table contains
facilityId
facilityName
facilityMapping table contains
facilityId
roomId
facilityQuantity
In facilityMapping table I want to create Reference to above two tables.
In service.xml I am trying to create Reference
<service-builder package-path="com.admin.services">
<namespace>rbms</namespace>
<entity name="rooms" local-service="true" remote-service="false">
<column name="roomId" type="int" primary="true"></column>
<column name="roomName" type="String"></column>
<column name="roomFloorNo" type="int"></column>
<column name="roomLocationName" type="String"></column>
<column name="roomCapacity" type="int"></column>
<column name="roomImages" type="String"></column>
</entity>
<entity name="facilities" local-service="true" remote-service="false">
<column name="facilityId" type="int" primary="true"></column>
<column name="facilityName" type="String"></column>
<!--
|- Finding Equipments using their Names and display it in form
|- It will help you to add new Room.
-->
<finder name="facilityName" return-type="Collection">
<finder-column name="facilityName"></finder-column>
</finder>
</entity>
<entity name="facilityMapping" remote-service="false" local-service="true">
<column name="facilityId" type="int"></column>
<column name="roomId" type="int"></column>
<column name="facilityQuantity" type="int"></column>
<column name="fk_fid" type="Collection" entity="com.admin.services.facilities" mapping-key="facilityId"></column>
</entity>
</service-builder>
Error : mapping-key must be declared for element-type column

As mapping-key is deprecated in new Liferay Version I am getting my work done using mapping-table attribute

Related

Set default fetch strategy to LAZY for entity ( XML)?

I have an entity defined in my XML persistence file as shown below. The entity/table in question has over 100 fields, but I only need a handful. Rather than marking all the fields I don't need with a fetch="LAZY" attribute, can I make the default fetch strategy for all columns for this table be LAZY and only mark the ones I need as fetch="EAGER" ?
I looked thru the Open JPA documentation here, but I did not see any reference to this. Is this possible in the XML entity-mappings?
<entity class="Users">
<table schema="dbo" name="Users"/>
<attributes>
<id name="id">
<column name="Id" column-definition="nchar" length="18"/>
</id>
<basic name="about" fetch="LAZY">
<column name="About" column-definition="nvarchar" length="1000"/>
</basic>
<basic name="accountId">
<column name="AccountId" column-definition="nchar" length="18"/>
</basic>
<basic name="alias">
<column name="Alias" column-definition="nvarchar" nullable="false" length="8"/>
</basic>
<basic name="auditCounter">
<column name="AuditCounter"/>
</basic>
<basic name="auditPercent">
<column name="AuditPercentc"/>
</basic>
<basic name="auditTarget">
<column name="Audit"/>
</basic>
<basic name="CenterId">
<column name="CenterId" column-definition="nchar" length="18"/>
</basic>
</attributes>
</entity>
It seems an entity graph is what you're after.
https://docs.oracle.com/javaee/7/tutorial/persistence-entitygraphs001.htm
What the above link implies is that you could mark the fields you need to be fetched eagerly, then use an empty load graph with your queries.
Or, you could use a fetch graph, explicitly listing the properties you're interested in, to control the fetch mode on a per-query basis.
The confusing part about the entity graph specification is that basic fields need to be explicitly marked as eagerly fetched as well, despite that (as far as annotation-based configuration goes, at least), the default value for Basic.fetch property is already FetchMode.EAGER. I have no idea what the behavior will be with XML-based configuration, so I suggest you go with the fetch graph approach and make sure it actually works.

Liferay 6.1 DynamicQuery - Complex Queries

I have an entity named DistributedLock :
<entity name="DistributedLock" local-service="true" remote-service="false">
<!-- PK fields -->
<column name="lockId" type="long" primary="true"/>
<!-- Other fields -->
<column name="ownerId" type="long"/>
<column name="createDate" type="long"/>
<column name="heartBeatInterval" type="long"/>
<column name="lastHeartBeat" type="long"/>
<column name="refCount" type="int"/>
<column name="endDate" type="long"/> <!-- optional -->
<column name="context" type="int"/> <!-- optional -->
<column name="state" type="int"/> <!-- optional -->
</entity>
In order to remove dead locks, I need to run this query :
DELETE FROM distributed_lock WHERE `lastHearBeat` < ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000) - `heartBeatInterval` - 2000;
How can I execute such a query using DynamicQuery?
Is there any better option?
Thanks in advance.

Hibernate Mapping - Join of two table to one flat class

I have two tables: patient_data and patient_diagnosis
Patient_data contains personal data of patient like: pid (pkey), gender, birth_date
patient_diagnosis contains the diagnosis data of the registered patients. It has fields like: record_id (pkey), pid (fkey to patient_data(pid)), diagnosis_date and other related fields.
Now, I want to join these two tables on pid and have all these fields in a single type of object.
Here is the mapping file:
<hibernate-mapping>
<class catalog="emr" name="in.Models.Emr" table="patient_diagnosis">
<id name="recordid" type="long">
<column name="record_id"/>
</id>
<property name="diagnosisDate" type="timestamp">
<column length="19" name="diagnosis_date" not-null="true"/>
</property>
<property name="snomedTermPrimary" type="long">
<column name="snomed_term_primary" not-null="true" />
</property>
<property name="snomedTermSecondary" type="string">
<column name="snomed_term_secondary" />
</property>
<property name="episodeNo" type="long">
<column name="episode_no" not-null="true" />
</property>
<property name="pid" type="long">
<column name="pid" not-null="true" />
</property>
<join table="patient_data">
<key column="pid"/>
<property name="gender" type="string">
<column name="gender" not-null="true"/>
</property>
<property name="birthDate" type="timestamp">
<column length="19" name="birth_date" not-null="true"/>
</property>
</join>
</class>
</hibernate-mapping>
But, the join applies on patient_diagnosis.record_id = patient_data.pid instead of patient_diagnosis.pid = patient_data.pid i.e. HQL applies on primary key of first table with mentioned column from second table.
Please provide the solution so that join can be applied on mentioned column from first with mentioned column from second table. Or is there another way out?
Please note that in case I didn't create classes for patient_data or patient_diagnosis. But, just Emr class having combination of fields of these tables is created.
Try giving foreign key
<id name="pid" type="java.lang.Long">
<column name="pid" />
<generator class="foreign">
<param name="property">patient_data</param>
</generator>
</id>
I am not sure but maybe this should work.
And
<one-to-one name="patient_data" class="in.Models.Emr"
cascade="save-update"></one-to-one>
Similarly in Join class
<one-to-one name="patient_diagnosis" class="in.Models.Emr"
cascade="save-update"></one-to-one>
I hope this helps you.

Java Hibernate Cascading Issue

---- Introductionary information and problem domain ----
Basicly I have 3 tables in a database: 'User', 'Item', 'ItemsPerUser'.
Table User:
username (PK);
password;
email
Table Item
name (PK)
Table ItemsPerUser
username (PK) (and FK);
item_name (PK) (and FK)
When I don't use cascading, I get an error: "Cannot add or update a child row: a foreign key constraint fails".
The mapping files are correct. I need some sort of cascading. It works when I add cascading in the set property of the many-to-many relationship to add non-existent data to User & Item, but it is overwriting data in ItemsPerUser. Whenever I save an object which contains one ore more items which was already entered in ItemsPerUser, it overwrites the row, even when the other part of the PK is not the same user. So basicly the previous user with that 'item' is overwritten by the new user with the same item.
It should always add a new row in the table ItemsPerUser if it is a new user, even with one or more item(s) whom is already entered by another User object.
---- Visual styled example ----
Assume I start with an empty database and I insert a new user Roger, who has two items: coffee and water. This is an example what happens (Hibernate handles this correct):
User ItemsPerUser Item
Roger Roger-coffee coffee
Roger-water water
Now when I insert a new user "Alfonzo" whom has the items coffee and soda, this happens:
User ItemsPerUser Item
Roger Alfonzo-coffee coffee
Alfonzo Roger-water water
Alfonzo-soda soda
---- Code example(s) ----
//Mapping for databag 'User' - !! NOTE: I have deleted the cascade rule in the XML
<hibernate-mapping>
<class name="databag.User" table="User" catalog="androiddb">
<id name="username" type="string">
<column name="username" length="45" />
<generator class="assigned" />
</id>
<property name="password" type="string">
<column name="password" length="45" not-null="true" />
</property>
<property name="email" type="string">
<column name="email" length="45" not-null="true" unique="true" />
</property>
<set name="items" inverse="false" table="itemsperuser">
<key>
<column name="username" length="45" not-null="true" />
</key>
<many-to-many entity-name="databag.Items">
<column name="item_name" length="45" not-null="true"/>
</many-to-many>
</set>
</class>
</hibernate-mapping>
//Mapping for Item
<hibernate-mapping>
<class name="databag.Item" table="item" catalog="androiddb">
<id name="name" type="string">
<column name="name" length="45" />
<generator class="assigned" />
</id>
<set name="users" inverse="false" table="itemsperuser">
<key>
<column name="item_naam" length="45" not-null="true" />
</key>
<many-to-many entity-name="databag.User">
<column name="username" length="45" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>
//Saving an object
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction trans = session.beginTransaction();
session.save((User)o);
trans.commit();
session.close();
Note: '(User)o' contains none, one or more items.
You can't set inverse="false" on both sides. Hibernate cannot persists both sets (users in Item and items in User) in the same table, unless one of them is called 'inverse', and can be savely ignored for writing. It will be filled up only when reading.
I'd set inverse="true" on the Item side.
Then you'd have to save items first, then adding them to a user, then saving the user.

How to #AttributeOverride of column names using xml configuration instead of JPA Anotations

I want to override column names in by subclass using xml.
i know this can be done using #AttributeOverride JPA Anotations but want to achieve the same using XML Configuration ?
You can use the embedded and attribute-override elements.
See Chapter 3. Overriding metadata through XML/3.1.3. Property level metadata.
An example from this document:
<attributes>
<id name="id">
<column name="fld_id"/>
<generated-value generator="generator" strategy="SEQUENCE"/>
<temporal>DATE</temporal>
<sequence-generator name="generator" sequence-name="seq"/>
</id>
<version name="version"/>
<embedded name="embeddedObject">
<attribute-override name"subproperty">
<column name="my_column"/>
</attribute-override>
</embedded>
<basic name="status" optional="false">
<enumerated>STRING</enumerated>
</basic>
<basic name="serial" optional="true">
<column name="serialbytes"/>
<lob/>
</basic>
<basic name="terminusTime" fetch="LAZY">
<temporal>TIMESTAMP</temporal>
</basic>
</attributes>

Categories

Resources