Fluent Nhibernate and Sql Server private setter error - sql-server-2008

I'm trying to complete some first step with fluent nhibernate with sql server express, to add this features in my project.
But got some errors. As I'm newbie to nhibernate, couldn't solve a problem for some time.
I have an entity with
Id { get; private set; }
accessors. And this entity is mapped to table with identity {1,1} column in sql server.
But during creating Session factory, I get an error:
The following types may not be used as proxies:Entity: method set_Id should be 'public/protected virtual' or 'protected internal virtual'
I understand that private setter is used to encapsulate setting of this property, but why do I get this error then?
PS: example on site of fluent for nhibernate is using sqllite db and everything is just fine.

This is an issue that has caused grief for many NH/FNH users, including me.
Until recently, NHibernate has allowed private setters with proxy objects. But starting with NH 3.2, private setters are no longer allowed - they must be "'public/protected virtual' or 'protected internal virtual'", as the error message says.
This is a breaking change for a lot of the FNH/NH sample code that's out there, and is especially confusing to newbies.

Declare the property as public virtual int Id { get; protected set; }. The proxy object generated by NHibernate will then be able to set the property.
Another solution can be to use a backing field:
private int id;
public int Id
{
get { return id; }
}
And then use mapping:
Map(x => x.Id).Access.CamelCaseField();

Related

LazyInitializationException when returning JSON in REST Webservice in Quarkus

I'm trying to build a simple application with Quarkus. Currently, I have two entity classes, which are related one-to-many:
#Entity
public class Person extends PanacheEntity {
public String name;
public LocalDate birthdate;
#OneToMany(mappedBy = "person")
public List<Address> addresses;
public static Person findByNameFirst(String name) {
return find("name", name).firstResult();
}
}
#Entity
public class Address extends PanacheEntity {
public String street;
...etc...
#ManyToOne
public Person person;
}
These are used by a simple REST webservice, which should store a Person to the database, select it again an return it:
#GET
#Path("storePerson")
#Produces(MediaType.APPLICATION_JSON)
#Transactional
public Person storePerson(
#QueryParam("name")String name,
#QueryParam("birthdate")String birthdate)
{
LocalDate birth = LocalDate.parse(birthdate, DateTimeFormatter.BASIC_ISO_DATE);
Person person = new Person(name, birth);
person.persistAndFlush();
Person p2 = Person.findByNameFirst(name);
return p2;
}
When calling the webservice the first time, the result is a JSON object with the stored data, which is as expected. When called again, an internal server error is thrown:
org.hibernate.LazyInitializationException: Unable to perform requested lazy initialization [Person.addresses] - no session and settings disallow loading outside the Session
As I understand, the error is thrown because the transaction only lasts until the storePerson method ends, but the conversion to JSON is happening outside of the method.
How can I prevent this error? I have read about the hibernate parameter "enable_lazy_load_no_trans" but it seems it is not supported in Quakus' application.properties.
The idea is to use a mapper framework such as MapStruct.
We don't recommend to directly expose your entities for 2 reasons:
the issue you have,
API management in the long run: you might have to change your model and not your API or the opposite.
There is an example here: https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-quarkus .
The Quarkus version used is a bit old but AFAICS it should still work with latest Quarkus.
You can make the error go away by using Hibernate.initialize(person.addresses), then the collection gets initialized before the transaction ends.

How to return complex objects with lazy loading to Web API

I am creating a Web API to expose Entity framework models.
Following a number of posts I have read, I have done a few bits in my webapi.config file
//Ignore circular references due to the VIRTUAL property on some objects.
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
//Remove XML formatter. We dont need XML, just JSON.
config.Formatters.Remove(config.Formatters.XmlFormatter);
DefaultContractResolver resolver = (DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver;
resolver.IgnoreSerializableAttribute = true;
In my Web API controllers, I am disabling ProxyCreation on the DB context.
Generally this is doing what I need to. However. I need to return a UserProfile object which has a virtual UserAdditionalInfos property as below.
[Serializable]
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UserId { get; set; }
public virtual List<UserAdditionalInfos> AdditionalDetails { get; set; }
}
If I try and make an API call to get the UserProfile object, I get an error at the point it tries to lazy load the UserAdditionalInfos list. I expect this as I have switched off the proxy creation. But if I switch it back on, I get a proxy encoded string returned in the JSON, rather than the object I would like.
Short of manually creating a 'flat' object for my API, is there any solid workaround available? Im sure this is a common problem?
Cheers
Ok I managed to figure this out, but adding in an optional 'Includes' string in my interfaces which I then split and separate and apply to the query itself. Thanks for the insight all!

RestyGWT JSON mapping with private fieldVisibility

I am currently prototyping replacing the GWT-RPC based backend of our application to a REST based API using RestyGWT on the frontend and Spring MVC on the backend.
My issue occurs during the Java <-> JSON type conversions that both frameworks attempt to resolve automatically. All of our data objects use private fields, and many of the fields do not provide java bean style setter methods. By default, neither framework would inspect the private fields of a class and so this conversion fails.
For Spring MVC it was simple enough to fix this by adding an annotation to the data objects:
#JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
For RestyGWT I have not found a suitable fix. The only available workaround I have found is to use default access to all fields and constructors which is far from ideal. Does anybody have a solution that will allow RestyGWT to inspect the private fields of a Java object?
Try using #JsonProperty and #JsonCreator (do not remeber if both are necessary) on your fields.
public abstract class Parent
{
#JsonCreator
public Parent(#JsonProperty("name") String name)
{
this.name = name;
}
public String getName()
{
return name;
}
private String name;
}

EF5 Database Migration with MySql

I encountered the below error when executing Enable-Migrations command against a MySql database:
PM> Enable-Migrations -ContextTypeName CodeFirstEFMySqlA1.Models.DataContext
Checking if the context targets an existing database...
System.ArgumentOutOfRangeException: startIndex cannot be larger than length of string.
Parameter name: startIndex
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.Data.Entity.Migrations.DbMigrator.ScaffoldInitialCreate(String namespace)
at System.Data.Entity.Migrations.Design.MigrationScaffolder.ScaffoldInitialCreate()
at System.Data.Entity.Migrations.Design.ToolingFacade.InitialCreateScaffoldRunner.Scaffold(MigrationScaffolder scaffolder)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.RunCore()
at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
startIndex cannot be larger than length of string.
Parameter name: startIndex
The project was created using:
- ASP.NET MVC4
- EF5 Code First
- MySql Database Server
- MySql.Data, MySql.Data.Entity
- A custom database initializer was implemented using System.Data.Entity.IDatabaseInitializer for creating migration history table.
Model:
public class Product
{
[Key]
public int Id { get; set; }
[Required, MaxLength(100)]
public string Name { get; set; }
public int Rank { get; set; }
[MaxLength(100)]
public string Type { get; set; }
}
After executing the command "Enable-Migrations" the Configuration.cs class was generated but no migration classes were generated. The same error "startIndex cannot be larger than length of string" is raised if I try to execute "Add-Migration" command.
My attempt is to test how well EF5 Code First and Database Migration capabilities could be used against a MySql database server. As I see database creation can be done using a custom database initializer, however I could not get database migrations working.
Any thoughts on this problem are highly appreciated
Thanks in advance!!
Thanks to Kirk Woll, I was able to find a solution for the above problem.
I used MySQL Data Connector v.6.6.4 and it has built in support for EF 5. Now Database Migrations works without a problem with MySql. Just to note I had to delete the previous database and let EF create a new one with Update-Database command.
Reference: MySQL 5.5 + .NET Connector + Entity Framework + Migrations = FormatException

PLINQO / LINQ-To-SQL - Generated Entity Self Save Method?

Hi I'm trying to create a basic data model / layer
The idea is to have:
Task task = TaskRepository.GetTask(2);
task.Description = "The task has changed";
task.Save();
Is this possible? I've tried the code below
Note: The TaskRepository.GetTask() methods detaches the Task entity.
I'd expect this to work, any ideas why it doesnt?
Thanks
public partial class Task
{
// Place custom code here.
public void Save()
{
using (TinyTaskDataContext db = new TinyTaskDataContext { Log = Console.Out })
{
db.Task.Attach(this);
db.SubmitChanges();
}
}
#region Metadata
// For more information about how to use the metadata class visit:
// http://www.plinqo.com/metadata.ashx
[CodeSmith.Data.Audit.Audit]
internal class Metadata
{
// WARNING: Only attributes inside of this class will be preserved.
public int TaskId { get; set; }
[Required]
public string Name { get; set; }
[Now(EntityState.New)]
[CodeSmith.Data.Audit.NotAudited]
public System.DateTime DateCreated { get; set; }
}
#endregion
}
Having done some reading I've realised I was implmenting the Repository pattern incorrectly. I should have been adding the Save method to the repository for conventions sake.
However, the actually problem I was having with regard to commiting the disconnected dataset was due to optimistic concurrency. The datacontext's job is to keep track of the state of it's entities. When entities become disconnected you loose that state.
I've found you need to add a timestamp field to the database table or I can set the UpdateCheck field on each column in my dbml file.
Here is some info about the UpdateCheck
Some useful links about disconnected Linq and plinqo
Great info on implementing the Repository pattern with LINQ
Short tutorial for implementing for updating and reattaching entities
Previously answer question
Rick Strahl on LINQ to SQL and attaching Entities
There is no need for this line (Task task = new Task();). The above should work although I've never seen it implemented in this manner. Have you thought about using the managers? Are you running into any runtime errors?
Thanks
-Blake Niemyjski