Updating model extension properties in Teiid fails - jboss

I'm having issues updating Teiid 8.6 model extension properties via JDBC. I can query the metadata, but I get an error while trying to issue an UPDATE command.
update "SYS"."Properties" set "Value" = 'VAL1' where "Name" = '{http://example.com/extmodel}prop1' and "UID" = 'mmuuid:e61b4b62-e874-4715-95a8-a5b04e916f5c' and "OID" is null
I get this:
org.teiid.jdbc.TeiidSQLException:
TEIID30492 Remote org.teiid.api.exception.query.QueryValidatorException:
TEIID30492 Metadata does not allow updates on the group: SYS.Properties
Is there a way to update these properties?

As the error message says the system metadata is not updatable at runtime. How you can update depends upon which kind of VDB you used. If you are using Dynamic VDB, then you can update the DDL, in OPTIONS properties for Table, Procedure etc.
If you are using the Designer, then you can select the table. stored procedure and update in the properties window.
Teiid 9.x roapmap has feature to update runtime metadata, once that feature is implemented then you can accomplish as you mention above.

Related

Hibernate persisting incorrect values

I have some Hibernate code running against a Postgres 9.5 DB, which looks like roughly like below (anonymized) -
Integer myEntityId = myEntity.getId();
getCurrentSession().evict(myEntity);
myEntity.setId(null);
MyEntity clonedMyEntity = (MyEntity)getCurrentSession().merge(myEntity);
myEntity.setMyBooleanField(false);
getCurrentSession().save(myEntity);
I have an entity myEntity with a large number of fields. I want to create a duplicate of the record with only 1 field value changed. To achieve this, I evict the entity from session, set Primary Key to null, merge it back to session, set the field I want to change, and then save the entity to DB. However, this code (which was working correctly for some time), is not working now. It sees incorrect value for the boolean field I am trying to modify - as a result violating some database constraints. Please help me fix this or suggest a better way to achieve what I am trying.
The error was happening not on adding this record but on add of another record to an audit table, triggered by the addition of this record. A coworker suggested me to use Eclipse Breakpoint view and use the add breakpoint option there and select the ConstraintViolationException class - this helped me to see the error for which trigger was failing and why and accordingly modify the data to suit the database constraint.

Entity Framework 6 - Always update properties that were manually setted by code - Change behavior of change tracker in proxy classes

This is Entity Framework 6.1.3 with .NET v4.0 and SQL Server 2008 R2.
In my, DB I have hundreds of tables with column LastChangedByUser in which I store the login of the user who last updated the row.
Unfortually, I have legacy triggers FOR UPDATE on almost all tables, and they all verify IF UPDATE(LastChangedByUser) and raise an error if this column is not included in the SET clause of the updated. I suppose the original developers did this to make sure the developers included every required column in their manually-written update queries.
By default EF only includes the properties that had their values changed when generating the SET clause of an UPDATE query. And this is causing problems in the following scenario: If previously some row was last changed by "user1", and the same "user1" tries to updates this row again later, EF is not including the LastChangedByUser column in it's generated SET clause, since it was set to the same value that it previously had. And the trigger is raising the error.
My legacy system (pre-EF) includes the LastChangedByUser in the SET clause in manually-written queries, regardless of the value being unaltered, so the trigger validations do OK for those old queries.
So I need to "mimic" this behavior in Entity Framework: if the code explicitly set a property value of a bound Entity proxy, I need its corresponding DbPropertyEntry to have the IsModified set to true regardless of the value being the same as the previous value.
I don't want to include all the columns in the SET cause (I tried this and had other trigger problems). I just want to include the columns that were set explicitly, like:
//this should make the property IsModified become true
//even if it was already "user1" when the entity loaded
myEntity.LastChangedByUser = "user1";
If the code simply dos not change the property (the setter is never called), then the property should remain with IsModified == false.
Is it possible to solve this? Maybe this default behaviour is too intrinsic and can't be changed...
Unfortunately I cannot just disable/drop the triggers, since they do tons of business rules on which the legacy system is dependent. And they are hundreds, so editing each one of them will be really tough...
Thank you!

How to Query a Read-Only Field with ORMLite

I am trying ORMLite as an ORM for a project I am developing. I am mapping a java class to a table that has some auditing fields (ie. updatedby, updatedtime, etc.). The auditing fields are maintained by the database using triggers to ensure that no matter what front-end the user is using these fields will always be correctly updated when a record is updated.
I need to include these fields in my client application to inform the user when the record was last updated, but the user can't change them. Is there a way to annotate the class so that ORMLite won't try to perform updates on these fields or include them in insert statements. The database will deny an update if these fields are included in an update statement (which is why I can't just write back the original value that was queried from the database).
I tried using the #DatabaseField(persisted = false) annotation on the Java fields, but then they don't get queried at all so the Java object is never populated with these fields.
Basically, I need these fields to be included in SELECT statements, but not included in INSERT or UPDATE statements (equivalent to a #DatabaseField(immutable = true) annotation).
Interesting pattern. ORMLite didn't support the feature at the time but now it does as of version 4.46.
There is now a #DatabaseField(readOnly=true) annotation field.

ADO.NET INSERT new record that has a foreign key in the table

I am fairly new to ADO.NET. I am ok with all the basic INSERT, etc. But now, I have a problem inserting a record into a table that contains a foreign key. I have done some research but am still stuck ... so here goes:
I want to INSERT a new record into a table called Professionals. It has a foreign key mapped to a different table. The FK is WAPublicUserID.
See Image:
When I create a data model, the WAPublicUserID isn't listed in the Properties of the Professional data model.
See Image:
Therefore, when I try to create an INSERT in my code, the WAPublicUserID field can't be found and I can't insert the record. The WAPublicUserID that I wish to use already exists in the WAPublicUser table that the FK is mapped to.
See Image:
How do I go about Inserting a new record in the Professionals table that contains a foreign key to an existing record in the WAPublicUser table? Thanks!
Someone has set "Include Foreign Key Properties in Model" to false.
Hence you have the navigation property of WAPublicUser but not the ForeignKey property.
This means you will have to Attach the relevant WAPublicUser object to the WAPublicUser property on the object you are trying to save.
I'd need a lot more code to know exactly what you are doing, but the basics of it are as follows:
If the WAPublicUser already exists:
Grab the existing entity from the database - OldEntity.
Update the OldEntity with the properties of the new one you are currently trying to save.
Save the (now updated) Old entity back to the database - because you have just read it, it should have the WAPublicUser reference already set.
If it doesn't:
Create a new WAPublicUser
Set the WAPublicuser property of the Professional object to the newly created WAPublicUser - that line goes where your code stops above.
myEnt.AddToProfessionals(pro);
myEnt.SaveChanges();
Got it. Here's how it works, in case anyone else reads this. #1 and #2 are focal points.
Mucho thanks to #BonyT for getting me on the right path ...
using (JONDOEntities myEnt = new JONDOEntities())
{
// #1) Need to create WAPublicUser object first
var wap = (from w in myEnt.WAPublicUsers
where w.WAPublicUserID == 981
select w).FirstOrDefault();
var proUser = (from p in myEnt.Professionals
where p.WAPublicUser.WAPublicUserID == wap.WAPublicUserID
select p).FirstOrDefault();
// If the record does not exist in the Professional table, insert new record.
if (proUser == null)
{
JONDOModel.Professional pro = new JONDOModel.Professional()
{
ProfessionalType = "unknown",
FirstName = "unknown",
LastName = "unknown",
PhoneNumber = "unknown",
WebsiteUrl = "unknown",
TaxID = "unknown",
BusinessInfo = "unknown",
ProfessionalLogo = "unknown",
IsApproved = true,
CATaxExempt = false,
WAPublicUser = wap // #2) Plug in the WAPublicUser object here
};
myEnt.AddToProfessionals(pro);
myEnt.SaveChanges();
}
OK, here's the real answer to my OP:
The asp.net website that I took over to manage was targeting .NET 3.5. Apparently, there are some issues with 3.5 and Entity Framework.
I converted the website to target .NET 4.0(*see below to see how). When I went to create the entity data model, voila , by default, it now included the Foreign Keys and therefore, I did not have any issues as described in OP.
If you run into this situation, you have to make sure that the web server is also upgraded to .NET 4.0. Because if you upgrade/convert the website files to target .NET 4.0, but your web server hasn't been upgraded, then although the website runs smooth on your dev machine (assuming that it has .NET 4.0 framework), it will crash on the live web server.
As an aside, .NET 4.0 framework will run apps that were built using previous versions of .NET (backward compatibility) ... however, an app that targets .NET 4.0 will not run in an environment with .NET 3.5 framework or prior.
CONVERT WEBSITE TO .NET 4.0:
Two ways to convert/upgrade website to .NET 4.0. 1) Usually, when you open a fresh copy and it's targeting 4.0, visual studio will ask if you want to convert/upgrade (Choose YES). 2) Within visual studio (commercial version), click WEBSITE tab, START OPTIONS, BUILD ... then you should see the options to change the "Target Framework" ...

How does Entity Framework detect rows affected by an update statement

I'm using Entity Framework, model first, self-tracking entities with Npgsql provider (VS2010 - .NET 4 target).
I'm trying to track optimistic concurrency exceptions, but my problem is that as soon as a column in the entity is marked as fixed, an OptimisticConcurrencyException is raised, even if the affected rows > 0.
After some digging exposed here, I would like to know why Entity Framework is issuing the update command through dbCommand.ExecuteReader(CommandBehavior.SequentialAccess) followed by a dbDataReader.Read() instead of dbCommand.ExecuteNonQuery() when the command text is a simple update statement ?
UPDATE "schema"."table"
SET "bool_column" = FALSE
WHERE ("id" = 7526) AND ("xmin" = 1249804)
Thanks.
The underlying provider should issue a SELECT statement right after an INSERT or UPDATE statement if there are any computed columns (StoreGeneratedPattern = "Computed" or "Identity") to retrieve.
Npgsql currently support only SERIAL during an INSERT operation.
It does not support computed column retrieval during an UPDATE operation. The consumer should call Refresh(RefreshMode.StoreWins, entity) to get values from the datasource.
This implies that Optimistic Concurrency is not supported in the current version of the Npgsql provider.