I am using liferay service builder jar for each plugin portlet. So when i have to insert a new record. I am using below code to insert the record.
XXX xxx = XXXLocalServiceUtil.createXXX(CounterLocalServiceUtil.increment(XXX.class.getName()));
xxx.setValue(value);
XXXLocalServiceUtil.addXXX(xxx);
Each table has a primary key with auto increment. But counter local service util will calculate its own counter value. I need each insert's primary key value. But in this case if first record is insert. 1 will be insert for the record but liferay counter will return 101 or 201 according to deployment.
This works fine
XXX xxx = new XXXImpl();
xxx.setValue(value);
XXXLocalServiceUtil.addXXX(xxx);
I got the exact key as per hibernate. But i can not use this. Because i am using jar file of service builder and there is not Impl class.
Service Builder xml file:
<entity name="XXX" local-service="true"
remote-service="false">
<column name="id" type="long" id-type="increment" primary="true"></column>
<column name="value" type="String" ></column></entity>
Another approach to explain:
Hi,
I am using service builder to my all plugin portlets. And i have custom table having primary key with autoincrement.
As of now i know there are these ways to insert records to table.
XXX xxx = XXXLocalServiceUtil.createXXX(0);
xxx.setValue(value);
XXXLocalServiceUtil.addXXX(xxx);
OR
XXX xxx = XXXLocalServiceUtil.createXXX(CounterLocalServiceUtil.increment()); // Global increment
xxx.setValue(value);
XXXLocalServiceUtil.addXXX(xxx);
OR
XXX xxx = XXXLocalServiceUtil.createXXX(CounterLocalServiceUtil.increment(XXX.class.getName())); // Increment table specific
xxx.setValue(value);
XXXLocalServiceUtil.addXXX(xxx);
In first if i want to get promary key value i gets 0, second long value, third incremented value wrt table name.
I am using thid one. Now if i re-deploy the service or portlet counter value will be incresed 101,201,...
And this can be handled by setting counter.increment.xxx.Class=1 or counter.increment=1.
But i just want to get database table incremented value from "xxx". So there is any way to do this.
Like this:
XXX xxx = new XXXImpl();
xxx.setValue(value);
XXXLocalServiceUtil.addXXX(xxx);
Here i can get the value which i want from database table.
Found the solution:
XXX xxx = XXXLocalServiceUtil.createXXX(0);
xxx.setValue(value);
xxx = XXXLocalServiceUtil.addXXX(xxx);
Now we have the incremented value in xxx. We just have to re-assign the object.
Related
I have a nodejs app with SQL Server. I want to be able to update a table for a "specific org" based on an insert and delete action. Let's say I have 2 tables as follows:
Project: projId, orgId, projName
Tasks: taskId, projId, taskName
Users: userId, orgId, userName
OrganizationStats: numberOfProjects, numberOfUsers, numberOfTasks orgId
So let's say I add a new project for an organization where orgId = 1. My insert statement from Nodejs would be:
insert into project (projId, orgId, projName)
values (${'projId'}, ${'orgId'}, 'New Project');
I want to write a trigger in SQL Server that adds 1 to the numberOfProjects column with orgId that's passed in.
create trigger updateProjectAfterInsert
on project
after insert
as
begin
update OrganizationStats
set numprojects = numberOfProjects + 1
where orgId = 'THE_INSERTED_ORGID_VALUE';
end;
My problem is I don't know how to pass the ${'orgId'} to the trigger.
I'm going to expand on my comment here:
Personally, I recommend against storing values which can be calculated by an aggregate. If you need such information easily accessible, you're better off making a VIEW with the value in there, in my opinion.
What I mean by this is that NumProjects has "no right" being in the table OrganizationStats, instead it should be calculated at the time the information is needed. You can't use an aggregate function in a computed column's definition without a scalar function, and those can be quite slow. Instead I recommend creating a VIEW (or if you prefer table value function) to give you the information from the table:
CREATE VIEW dbo.vw_OrganisationStats AS
SELECT {Columns from OrganizationStats},
P.Projects AS NumProjects
FROM dbo.OrganizationStats OS
CROSS APPLY (SELECT COUNT(*) AS Projects
FROM dbo.Projects P
WHERE P.OrgID = OS.OrgID) P;
I use a CROSS APPLY with a subquery, as then you don't need a huge GROUP BY at the end.
I think what you want this something like this:
CREATE TRIGGER updateProjectAfterInsert
ON Project
AFTER INSERT
AS
BEGIN
UPDATE OrganizationStats
SET NumProjects = NumProjects + 1
WHERE OrgId IN (SELECT OrgId FROM inserted);
END;
Also note, Triggers must always assume multiple rows. It's possible to insert multiple rows, update multiple rows, and delete multiple rows. The "inserted" and "deleted" collections contain the data needed ("inserted" contains the rows being inserted, "deleted" contains the rows being deleted, and on an update "inserted" contains the values after the update, and "deleted" contains the values before the update).
When adding a new inventoryitem through the API we have a few list based custom fields we need to fill in. I want to be able to use the string value for the field but when I try to the call errors out.
We have a custom list with two values:
InternalId 1 is "LTL"
InternalId 2 is "FedEx"
I have tried sending the value across as a StringCustomFieldRef and when setting the value to the string value of the "LTL" we get an invalid ref error. When setting the value to the internalId of 1 it works.
I also tried using a SelectCustomFieldRef and when setting the value->name to the string value of "LTL" it errors like we did not pass the value at all. When we set value->internalId to 1 it works.
Is it possible to just pass in the string value?
Does not work:
$customField1 = new StringCustomFieldRef();
$customField1 ->value = "LTL";
$customField1 ->scriptId = 'custitem_zu_zu_fulfill_pref';
Works:
$customField1 = new StringCustomFieldRef();
$customField1 ->value = "1";
$customField1 ->scriptId = 'custitem_zu_zu_fulfill_pref';
This is the error response:
<platformCore:statusDetail type="ERROR">
<platformCore:code>INVALID_KEY_OR_REF</platformCore:code>
<platformCore:message>Invalid custitem_zu_zu_fulfill_pref reference key LTL.</platformCore:message>
</platformCore:statusDetail>
No, unfortunately you cannot set a field with the Name value--you will have to use the internalId. If your custom field is list-based, then you should be using SelectCustomFieldRef or MultiSelectCustomFieldRef.
If you wish to use the Name value, you can perform a CustomListSearchBasic to get the Name and internalId of each item, and match that to your chosen Name.
1 .For default value I have tried :
#Required
#Column(name="semester")
#DefaultValueCalculator(value=StringCalculator.class, properties=#PropertyValue(name="value", value="173"))
private String semester;
Getting error :
Error calculating default value
2 . Another Problem is I want to view column of another table into a table.
Table .
- Room [id, name]
- RoomAssigned [id , capacity , type ,status ]
In view/UI , I am showing RoomAssigned which has CRUD .
Now its showing column -
[id,capacity,type,status]
I want to add another column [name] from "Room" table . Here "Room" id is foreign key.
I want to get a view with view / UI :
[id,name,capacity,type,status]
I am new in OpenXava.Thanks in advance.
About the second point, you have to put the reference name in the #View members, use a #ReferenceView in the reference and create a #View in the referenced entity.
Read this documentation first:
http://openxava.wikispaces.com/view_en
In the following instance, I have tried to simplify an issue to root components.
I've got a very simple SQL Azure database where I created a test table called Table1. Azure creates an ID field with Is Required, Is Primary Key checked. It will NOT allow to check the box Is Identity. There are a couple of other fields which are simply required.
In my VS2012 Project, I have created an LinqToSql Class which created a ProductionDataClasses1.dbml object.
I simply want to add a record to this table thru the method shown below. From what I am reading, ID would be set during the SubmitChanges() after InsertOnSubmit(NewRecord) is specified.
It does work the first time but value is set to zero. On subsequent save, I get an exception (basically it a duplicate record because ID=0 already exists).
To put this into context, I have included some sample code below. The idea is to first check if the record exists and update. If not, I want to add a record.
My question is... Do I need to manually set ID? If so, how do I set the value to an int and how to a retrieve the next value. I tried changing to a Guid but not allowed.
Here is my code sample:
public bool AddTestRecord(string someValue)
{
ProductionDataClasses1DataContext context = new ProductionDataClasses1DataContext();
try
{
var ExistingRecord = context.Table1s.SingleOrDefault(c => c.TextKey == someValue);
if (ExistingRecord == null)
{
var NewRecord = new Table1();
// NewRecord.ID = ???? ; How Do I Manually Set. It is getting set to 0 causing a duplicate value exception
NewRecord.TextKey = someValue;
NewRecord.AnotherValue = DateTime.Now.ToShortTimeString();
context.Table1s.InsertOnSubmit(NewRecord);
}
else
{
ExistingRecord.AnotherValue = DateTime.Now.TimeOfDay.ToString();
}
context.SubmitChanges();
return true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
context.SubmitChanges();
}
}
I would suggest manually running a SQL script to alter the table and make the column an identity. Look at this answer
Adding an identity to an existing column
Thanks for your reply.
I just was finally able to make this work on a new table and will try to follow along your instructions to make modifications to my real table. My code (as written above) was OK so the issue is in the SQL Azure table definition.
I found the issue is that when you create a new table in SQL Azure, it creates a table with three fields, ID, Column1, Column2. By default, ID is set as the Primary Key but none are checked as Is Identity.
To make this work, I made ID the Is Identity and unchecked PrimaryKey and Column1 the In Primary Key. Thus when a new record is saved, the ID is set and Column1 is checked to make sure it is not already in the system. I had to do this when the table was first created. Once saved, it would not allow me to change.
Afterwards, I updated my Linq To SQL class and dropped the new table in. I noted that now the AutoGenerated Value on ID and PrimaryKey on Column1 was set and my code worked.
Objective:
I have a table called Publication that contains Id, RecordId, EntityType and a couple other columns. I select all the records that need to be published to another database from that table. I then loop that collection to process the records and move the records to the other db.
Background:
The EntityType column is used to Identify the Set that the context needs to retrieve. I also use reflection to create a object of that type to see if it implements a certain type of interface. If the record being processed does implement that interface then I know that the RecordId for that record in the Publication table is not a PK in the Set() but rather a FK.
this code works fine when I am going after the PK values for EntityTypes that do not inherit the specific interface.
object authoringRecordVersion = PublishingFactory.AuthoringContext.Set(recordType.Entity.GetType()).Find(record.RecordId);
Problem:
DbContext.Set(EntityType).Find(PK) goes after the PrimaryKey value. How can I tell Set() to search like this sudo code example since 'Where' is not allowed
object authoringRecordVersion = PublishingFactory.AuthoringContext.Set(recordType.Entity.GetType()).Where(c => c.HeaderRecordId == record.RecordId)
Update:
I am working on Implementing the following. Will advise results tomorrow
var sql = "SELECT * from " + record.Entity + " WHERE HeaderRecordId = '" + record.RecordId + "'";
authoringRecordVersion = PublishingFactory.AuthoringContext.Set(recordType.Entity.GetType()).SqlQuery(sql).AsNoTracking();
.SqlQuery(sql).AsNoTracking();
does work effectively. Don't know why I didn't see this earlier.