SQL Server 2014 Native Client (12.0.0.0) - Any way to force Assembly Version (e.g. SqlConnectionString "Type System Version")? - ado.net

I am writing an application (using .NET Framework 4.5.2 + SQL Server 2014 installed locally). The application needs to support both SQL Server 2014 and previous versions.
When reading data using the inbuilt SQLCLR-types (SqlGeometry, SqlGeography, SqlHierarchyID), the standard ADO.NET methods (e.g. DataReader.GetValues()) use the 10.0.0.0 assembly, and throw an exception due to a mismatch with the loaded (v11 or v12) version.
The reasoning is documented (though it takes a while to spot) in the Breaking Changes in SQL Server 2012 (for the 11.0.0.0 assembly). For SQL Server 2012, there are three workarounds listed:
Use Type System Version=SQL Server 2012 in the SQLConnection.ConnectionString
OR: Use app.config / runtime / assemblyBinding / dependentAssembly to re-map v10.0.0.0 to v11.0.0.0
OR (not a very "neat" way to handle it): rewrite your own code to manually deserialize from a SqlBytes instance...
When developing from a computer with SQL Server 2014 installed, the assembly version is v12.0.0.0, and similar issues arise:
System.InvalidCastException: Unable to cast object of type Microsoft.SqlServer.Types.SqlGeometry to type Microsoft.SqlServer.Types.SqlGeometry.
For SQL Server 2014 (other than the horrible manual deserialize approach), there only seems to be one workaround (not officially documented in the breaking-changes) - it would appear that the v4.5 SqlConnection hasn't yet caught up with the version of SQL Server:
Use app.config / runtime / assemblyBinding / dependentAssembly to re-map v10.0.0.0 to v12.0.0.0
Question: other than re-mapping v10.0.0.0 to v12.0.0.0 in app.config (which seems to work), is there any other (easier) approach that will use the referenced assembly version?
A quick code-example below shows the failure (without the assembly-remapping in place):
private static void DoStuff()
{
SqlGeography geog_val = SqlGeography.STGeomFromText(new SqlChars("POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))"), 4326);
SqlGeometry geom_val = SqlGeometry.Parse("LINESTRING(1 1,2 3,4 8, -6 3)");
prm_geog.Value = DBNull.Value; prm_geom.Value = geom_val; ReadReturnedSpatialColumns(cmd);
prm_geog.Value = geog_val; prm_geom.Value = DBNull.Value; ReadReturnedSpatialColumns(cmd);
}
private static void ReadReturnedSpatialColumns(SqlCommand cmd)
{
using (var dr = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
dr.Read(); var items = new object[2]; dr.GetValues(items);
var geog_test = dr.IsDBNull(0) ? SqlGeography.Null : (SqlGeography)items[0];
var geom_test = dr.IsDBNull(1) ? SqlGeometry.Null : (SqlGeometry)items[1];
}
}

This issue still exists with Framework 4.6.1 and there appears to be no workaround apart from the 3 you've already discovered. So the short answer to your question is no.
However I would question if you really need version 12 of the spatial types, because (as far as I can tell) they don't add anything over the v11 types. If you'd prefer to use the v11 types so you can use the Type System Version=SQL Server 2012 workaround, you can install the Nuget package that incorporates all three versions (10, 11, 12) - it's specifically designed to allow you to deploy to servers where MSSQL may not be installed.
As a bonus, referencing that package directly and using Type System Version=SQL Server 2012 will ensure that your app will always be using the 2012 spatial types, so upgrading to SQL 2016 won't break anything if it decides to return a different version of them (e.g. 13, or 14, or whatever 2016 will use) by default.

Related

FIWARE Orion Runtime Error

I am using FIWARE Orion (in a docker image) and I am facing with the possibility of losing some records. I looked in the log and came with a number of errors like the following:
time=Sunday 17 Dec 21:03:13 2017.743Z | lvl=ERROR | corr=N/A | trans=N/A | from=N/A | srv=N/A | subsrv=N/A | comp=Orion | op=safeMongo.cpp[287]:setStringVector | msg=Runtime Error (element 0 in array was supposed to be an string but type=3 from caller mongoSubCacheItemInsert:225)
According to http://fiware-orion.readthedocs.io/en/0.26.1/admin/logs/ these kind of errors (Runtime) "may cause the Context Broker to fail" and "should be reported to the Orion development team using the appropriate channel" and this is exactly what I am doing.
Any help, will be highly appreciated.
Thank you very much in advance.
EDIT: Orion version is 1.5.0-next
EDIT: It has been upgraded to 1.10.0
EDIT: After executing ps ax | grep contextBroker I receive the following results:
23470 ? Ssl 4:24 /usr/bin/contextBroker -fg -multiservice -dbhost mongodb
EDIT: The problem occurs periodically. Actually, it takes place exactly every minute:
time=Wednesday 20 Dec 20:50:27 2017.235Z
time=Wednesday 20 Dec 20:51:27 2017.237Z
etc.
Orion 1.5.0-next means some running version between 1.5.0 (released in October 2016) and 1.6.0 (released in December 2016). In the best case, your version is one year old, which is pretty much time.
Thus, I recommend you to upgrade to the newest available Orion version (in the moment of writting this, that version is 1.10.0, released in December 2017). We have solved some "overlogging" problems in the delta of changes between 1.6.0 and 1.10.0 and the one you mention could be one of them.
If the problem stills after upgrading, tell about it in a comment to the answer and we'll keep debuging.
Diagnosis
The 60 seconds periodicity is exactly the subscriptions cache refresh interval with default configuration (your CLI confirms your are not using different setting for subscriptions cache).
Looking in detail to the line refered by the log trace in Orion 1.10.0 source code:
setStringVectorF(sub, CSUB_CONDITIONS, &(cSubP->notifyConditionV));
The log error means that Orion expects an array of strings for the CSUB_CONDITIONS field in a document of the subscription collection at database, but some of the elements in the array (or all) aren't strings but a objects (type 3 means object, as BSON specification details).
CSUB_CONDITIONS constant corresponds to conditions field at DB. Note this field changed at Orion 1.3.0. Before 1.3.0, for instance 1.2.0, it was an array of objects:
"conditions" : [
{
"type" : "ONCHANGE",
"value" : [ "temperature " ]
}
]
From 1.3.0 on, it was simplified to an array of strings:
"conditions" : [ "temperature" ]
So my hypothesis is that in some moment in the past that Orion instance was updated crossing the 1.3.0 boundary but without applying the procedure to migrate data (or the procedure was applied but failed in some way).
Solution
Given that you are in a situtation in which your data at Orion database is probably inconsistent, the cleanest solution would be to remove your database. Or, at least, the csubscollection.
However, this is possible only in the case you can regenerate the data to be deleted in an easy way. If that is not feasible, you can try with the procedure to migrate data. In particular, the csub_merge_condvalues.py script should fix the problem although I'd recommend to apply the full procedure in order to fix other potential inconsistencies.
Take into account that the migration procedure was designed to be applied before start using the new Orion version. It seems you have been using post-1.3.0 Orion with pre-1.3.0 data for a time, so your data can have evolved in some unexpected way the procedure couldn't fix. Anyway, even in this case the procedure is better than nothing :)
Note that if you are using multiple services (it seems so for the -multiservice CLI parameter) you have to apply the clean/migration procedure to every per-service database.

Grails afterInsert hook issue with Hibernate 5.1 and PostgreSQL

In an existing Grails 3.1.15 application, recently upgraded to Hibernate 5.1, an odd issue with afterInsert (or other) hooks started to appear. After some hours of testing, I could track this down to Hibernate 5.1 + PostgreSQL combination - issue is not reproducible with H2. To reproduce, create a simple application consisting of 2 domain objects - an Audit trail and a User, as shown here:
class Audit {
Date dateCreated
String auditData
}
class User {
String name
String email
def afterInsert() {
new Audit(auditData: "User created: $this").save()
}
}
The code above works OK with Hibernate 4, however, if the application is upgraded to Hibernate5 plugin + Hibernate 5.1.x (tested with 5.1.0.Final and 5.1.5.Final) the above scenario will always lead to a ConcurrentModificationException when you attempt to save a new User instance. You can just use a scaffold controller to reproduce. Note this only happens with PostgreSQL as the data source - with H2 it would still work OK.
Now, according to GORM Docs (see chapter 8.1.3) one should use a new session when attempting to save other objects in beforeUpdate or afterInsert hooks anyway:
def afterInsert() {
Audit.withNewSession() {
new Audit(auditData: "User created: $this").save()
/* no exception logged, but Audit instance not preserved */
}
}
But this wouldn't really resolve the issue with PSQL. The exception is gone, the User instance is persisted, but the Audit instance is not saved. Again, this code would work OK with H2. To really avoid the issue with PSQL, you would have to manually flush the session in afterInsert:
def afterInsert() {
Audit.withNewSession() { session ->
new Audit(auditData: "User created: $this").save()
session.flush()
/* finally no exceptions, both User and Audit saved */
}
}
Question: is this a bug, or is this expected? I find it a bit suspicious that the manual flush is required in order for the Audit instance to be persisted - and even more so when I see it works without a flush with H2 and only seems to affect PostgreSQL. But I couldn't really find any reports - any pointers are appreciated!
For the sake of completeness, I tested with the following JDBC driver versions for PostgreSQL:
runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
runtime 'org.postgresql:postgresql:9.4.1208.jre7'
runtime 'org.postgresql:postgresql:42.0.0'
And for the upgrade to Hibernate 5.1, the following dependencies were used:
classpath "org.grails.plugins:hibernate5:5.0.13"
...
compile "org.grails.plugins:hibernate5:5.0.13"
compile "org.hibernate:hibernate-core:5.1.5.Final"
compile "org.hibernate:hibernate-ehcache:5.1.5.Final"

visual basic 5 run-time error 429 dbengine.workspaces

I had an application perfectly working under Windows XP (32 bit). Moving to Windows 7 (64 bit) and compiling gives me the error run time error 429 ActiveX component can't create object in the module (second line, "set mydb=...", see code) where I make the connection with the MS Access database (Access 2013 in Windows 7 64 bit). In Windows XP it was an Access 2000 database with extension .mdb. Now it is Access 2013 with extension .accdb.
In the references I replaced the Microsoft Office DAO 3.5 library with the Microsoft Office 15.0 Access Database Engine Object Library, but this doesn't solve the problem. (If I leave the DAO object library, then I get run time error 3343 unrecognized database format on the same line.)
I'm not sure if I have to put in the components of the forms the 32 or the 64 bit version. (For example, dbrgid32.ocx under windows\system32 or under windows\sysWOW64 ... or does it not matter?)
Sub pldata()
Set mydb = DBEngine.Workspaces(0).OpenDatabase("D:\ETC\Gegevens\ETC2015.accdb", False, False, "MS Access")
'Set mydb = DBEngine.Workspaces(0).OpenDatabase("D:\ETC\Gegevens\ETC2015.accdb")ess")
Set myrstadres = mydb.OpenRecordset("select * from dbadres order by naam")
End Sub

getSchema in PostgreSQL JDBC driver throws java.lang.AbstractMethodError or java.sql.SQLFeatureNotSupportedException

I'm using Postgresql 8.4 and my application is trying to connect to the database.
I've registered the driver:
DriverManager.registerDriver(new org.postgresql.Driver());
and then trying the connection:
db = DriverManager.getConnection(database_url);
(btw, my jdbc string is something like: jdbc:postgresql://localhost:5432/myschema?user=myuser&password=mypassword)
I've tried various version of the jdbc driver and getting two type of errors:
with jdbc3:
Exception in thread "main" java.lang.AbstractMethodError: org.postgresql.jdbc3.Jdbc3Connection.getSchema()Ljava/lang/String;
with jdbc4:
java.sql.SQLFeatureNotSupportedException: Il metodo ½org.postgresql.jdbc4.Jdbc4Connection.getSchema()╗ non Þ stato ancora implementato.
that means: method org.postgresql.jdbc4.Jdbc4Connection.getSchema() not implemented yet.
I'm missing something but I don't know what..
------ SOLVED ---------
The problem were not in the connection String or the Driver version, the problem were in the code directly above the getConnection() method:
db = DriverManager.getConnection(database_url);
LOGGER.info("Connected to : " + db.getCatalog() + " - " + db.getSchema());
It seems postgresql driver doesn't have getSchema method, as the java console were often trying to say to me..
The Connection.getSchema() version was added in Java 7 / JDBC 4.1. This means that it is not necessarily available in a JDBC 3 or 4 driver (although if an implementation exists, it will get called).
If you use a JDBC 3 (Java 4/5) driver or a JDBC 4 (Java 6) driver in Java 7 or higher it is entirely possible that you receive a java.lang.AbstractMethodError when calling getSchema if it does not exist in the implementation. Java provides a form of forward compatibility for classes implementing an interface.
If new methods are added to an interface, classes that do not have these methods and were - for example - compiled against an older version of the interface, can still be loaded and used provided the new methods are not called. Missing methods will be stubbed by code that simply throws an AbstractMethodError. On the other hand: if a method getSchema had been implemented and the signature was compatible that method would now be accessible through the interface, even though the method did not exist in the interface at compile time.
In March 2011, the driver was updated so it could be compiled on Java 7 (JDBC 4.1), this happened by stubbing the new JDBC 4.1 methods with an implementation that throws a java.sql.SQLFeatureNotSupportedException, including the implementation of Connection.getSchema. This code is still in the current PostgreSQL JDBC driver version 9.3-1102. Technically a JDBC-compliant driver is not allowed to throw SQLFeatureNotSupportedException unless the API documentation or JDBC specification explicitly allows it (which it doesn't for getSchema).
However the current code on github does provide an implementation since April this year. You might want to consider compiling your own version, or ask on the pgsql-jdbc mailinglist if there are recent snapshots available (the snapshots link on http://jdbc.postgresql.org/ shows rather old versions).

Entity Framework with EntityDataSource throws MetadataException when installed on Windows 2008 server

I have a problem with installing a Web Application on a server which is using an EntityDataSource and the .NET Framework June CTP.
I posted the question on the MSDN Forums but still have no answer:
EF with POCO templates and DbContext throws MetadataException when installed on server
The following Exception is throwed when installing the application on a windows 2008 server with IIS 7 and when using an EntityDataSource in combination with the June CTP Framework which we need for using POCO and the DbContext.
System.Web.HttpUnhandledException (0x80004005): Exception of type
'System.Web.HttpUnhandledException' was thrown. --->
System.Data.MetadataException: Schema specified is not valid. Errors:
Library.csdl(2,9) : warning 0005: Could not find schema information
for the attribute 'Namespace'. Library.csdl(2,34) : warning 0005:
Could not find schema information for the attribute 'Alias'.
Library.csdl(2,2) : error 0010: The element Schema in namespace
http://schemas.microsoft.com/ado/2009/11/edm was unexpected for the
root element. The expected Schema in one of the following namespaces:
http://schemas.microsoft.com/ado/2006/04/edm,
http://schemas.microsoft.com/ado/2007/05/edm,
http://schemas.microsoft.com/ado/2008/09/edm. at
System.Data.Metadata.Edm.EdmItemCollection.LoadItems(IEnumerable1
xmlReaders, IEnumerable1 sourceFilePaths, SchemaDataModelOption
dataModelOption, DbProviderManifest providerManifest, ItemCollection
itemCollection, Boolean throwOnError)
When we create a test project without the June CTP Framework it is working. When we do not use the EntityDataSource with the June CTP Framework it works too. We developed some months with this EntityDataSource so it's not easy to change the code and use something else.
Your server appears to have .NET 3.5 SP 1, and the CTP requires .NET 4. The schemata in the error message (2006-8) are EF 10 2009/11/edm are EF 4.