Code First Model Works on One PC, but Fails on Another - entity-framework-4.1

Background
Code first model using ef4.1. Database is Oracle so we're using Devart dotConnect as well.
Issue
After deploying the app to a server, saw errors with sql statements and invalid column names. Everything worked fine on my dev PC.
Created a small test console app and replicated the behavior. On my pc, not debugging but just running the app, it works fine and selects data correctly. On the server, the select statement has two extra column names for foreign keys.
Entity
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.ServiceModel.DomainServices.Server;
using log4net;
namespace Cul2.Model
{
[Table("LAB_REQUISITION")]
public class LabRequisition : EntityBase
{
public LabRequisition()
{
Attributes = new Collection<LabRequisitionAttribute>();
Samples = new Collection<LabSample>();
}
[Key]
[Column("REQUISITION_ID")]
public long? RequisitionId { get; set; }
[Column("MATERIAL_ID")]
public long? MaterialId { get; set; }
[Include]
[Association("Material", "MaterialId", "MaterialId", IsForeignKey = true)]
public virtual LabMaterial Material { get; set; }
[Column("LAB_NUMBER")]
public int? LabNumber { get; set; }
[Column("COLLECTOR_ID")]
public long? CollectorId { get; set; }
[Include]
[Association("Collector", "CollectorId", "UserId")]
[ForeignKey("CollectorId")]
public virtual ComUser Collector { get; set; }
[Column("RECEIVER_ID")]
public long? ReceiverId { get; set; }
[Include]
[Association("Receiver", "ReceiverId", "UserId")]
[ForeignKey("ReceiverId")]
public virtual ComUser Receiver { get; set; }
[Column("COLLECTION_DATE")]
public DateTime? CollectionDate { get; set; }
[Column("STATUS_ID")]
public long? StatusId { get; set; }
[Include]
[Association("Status", "StatusId", "StatusId", IsForeignKey = true)]
public virtual LabStatus Status { get; set; }
[Column("IS_ACTIVE")]
public bool IsActive { get; set; }
[Column("TEMPLATE_ID")]
public long? TemplateId { get; set; }
[Include]
[Association("Template", "TemplateId", "TemplateId", IsForeignKey = true)]
public virtual LabTemplate Template { get; set; }
[Column("REASON_ID")]
public long? ReasonId { get; set; }
[Include]
[Association("Reason", "ReasonId", "ReasonId", IsForeignKey = true)]
public virtual LabReason Reason { get; set; }
[Column("RECEIVED_DATE")]
public DateTime? ReceivedDate { get; set; }
[Include]
[Association("Samples", "RequisitionId", "RequisitionId")]
[ForeignKey("RequisitionId")]
public ICollection<LabSample> Samples { get; set; }
[Include]
[Association("Attributes", "RequisitionId", "RequisitionId")]
public ICollection<LabRequisitionAttribute> Attributes { get; set; }
public override string ToString()
{
return LabNumber == null ? "New" : LabNumber.ToString();
}
}
}
On my PC, this is the schema sql that is generated for that entity:
-- Table LAB_REQUISITION
CREATE TABLE LAB_REQUISITION (
REQUISITION_ID NUMBER(18) NOT NULL,
MATERIAL_ID NUMBER(18) NULL,
LAB_NUMBER NUMBER(10) NULL,
COLLECTOR_ID NUMBER(18) NULL,
RECEIVER_ID NUMBER(18) NULL,
COLLECTION_DATE TIMESTAMP(7) NULL,
STATUS_ID NUMBER(18) NULL,
IS_ACTIVE NUMBER(1) NOT NULL,
TEMPLATE_ID NUMBER(18) NULL,
REASON_ID NUMBER(18) NULL,
RECEIVED_DATE TIMESTAMP(7) NULL,
ROW_VERSION NUMBER(18,2) NULL,
CREATED TIMESTAMP(7) NULL,
CREATED_BY_ID NUMBER(18) NULL,
LAST_UPDATED TIMESTAMP(7) NULL,
LAST_UPDATED_BY_ID NUMBER(18) NULL,
PRIMARY KEY (REQUISITION_ID)
)
/
On the server, this is the schema generated:
-- Table LAB_REQUISITION
CREATE TABLE LAB_REQUISITION (
REQUISITION_ID NUMBER(18) NOT NULL,
MATERIAL_ID NUMBER(18) NULL,
LAB_NUMBER NUMBER(10) NULL,
COLLECTOR_ID NUMBER(18) NULL,
RECEIVER_ID NUMBER(18) NULL,
COLLECTION_DATE TIMESTAMP(7) NULL,
STATUS_ID NUMBER(18) NULL,
IS_ACTIVE NUMBER(1) NOT NULL,
TEMPLATE_ID NUMBER(18) NULL,
REASON_ID NUMBER(18) NULL,
RECEIVED_DATE TIMESTAMP(7) NULL,
ROW_VERSION NUMBER(18,2) NULL,
CREATED TIMESTAMP(7) NULL,
CREATED_BY_ID NUMBER(18) NULL,
LAST_UPDATED TIMESTAMP(7) NULL,
LAST_UPDATED_BY_ID NUMBER(18) NULL,
"Collector_UserId" NUMBER(18) NULL,
"Receiver_UserId" NUMBER(18) NULL,
PRIMARY KEY (REQUISITION_ID)
)
/
The Collector_UserId and Receiver_UserId columns are incorrect and they are causing the SQL select errors.
I can't figure out why the model would generate correct SQL on my Dev PC but on the server it would generate the bogus extra columns.
The app is exactly the same on Dev PC and the server except on the server I had to add the DbProviderFactories section to the app.config -- on my PC i'm guessing since Devart is installed that it is already registered. Otherwise exactly the same.
On my Dev PC the Devart libraries are being loaded from GAC whereas on the server they are loaded from the bin folder. As far as I can tell the versions are identical.
Update 1 - Versions:
These are the versions and path for the EF and devart assemblies.
SERVER
Assembly: EntityFramework
EntityFramework, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
file:///C:/apps/Cultivate.TestConsole/EntityFramework.DLL
Assembly: Devart.Data.Oracle.Entity
Devart.Data.Oracle.Entity, Version=7.2.96.0, Culture=neutral, PublicKeyToken=09af7300eec23701
file:///C:/apps/Cultivate.TestConsole/Devart.Data.Oracle.Entity.DLL
Assembly: Devart.Data.Oracle
Devart.Data.Oracle, Version=7.2.96.0, Culture=neutral, PublicKeyToken=09af7300eec23701
file:///C:/apps/Cultivate.TestConsole/Devart.Data.Oracle.DLL
Assembly: Devart.Data
Devart.Data, Version=5.0.555.0, Culture=neutral, PublicKeyToken=09af7300eec23701
file:///C:/apps/Cultivate.TestConsole/Devart.Data.DLL
DEV PC
Assembly: EntityFramework
EntityFramework, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
file:///C:/dev/tfs/cul2/source/Cul2.Actions.Lab.TestConsole/bin/Debug/EntityFramework.DLL
Assembly: Devart.Data.Oracle.Entity
Devart.Data.Oracle.Entity, Version=7.2.96.0, Culture=neutral, PublicKeyToken=09af7300eec23701
file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Devart.Data.Oracle.Entity/v4.0_7.2.96.0__09af7300eec23701/Devart.Data.Oracle.Entity.dll
Assembly: Devart.Data.Oracle
Devart.Data.Oracle, Version=7.2.96.0, Culture=neutral, PublicKeyToken=09af7300eec23701
file:///C:/Windows/assembly/GAC_MSIL/Devart.Data.Oracle/7.2.96.0__09af7300eec23701/Devart.Data.Oracle.dll
Assembly: Devart.Data
Devart.Data, Version=5.0.555.0, Culture=neutral, PublicKeyToken=09af7300eec23701
file:///C:/Windows/assembly/GAC_MSIL/Devart.Data/5.0.555.0__09af7300eec23701/Devart.Data.dll

Related

I want to implement foreign key in my Springboot project but I get the following errors

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.Tue Oct 10 17:11:14 IST 2018 There was an unexpected error (type=Internal Server Error, status=500). could not execute statement; SQL [n/a]; nested exception is org.
hibernate.exception.SQLGrammarException: could not execute statement.
STS Error:
Before changing the code
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolation
Exception
: Cannot add or update a child row: a foreign key constraint fails
(workdemo.officeinfo, CONSTRAINT idFOREIGN KEY (id) REFERENCES mytable
(id))
After implementing joincolumn
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'entityManagerFactory' defined in class path
resource [org/springframework/boot/autoconfigure/orm/jpa/
HibernateJpaConfiguration.class]: Invocation of init method failed;
nested exception is org.hibernate.AnnotationException: No identifier
specified for entity:com.infidata.modal.MyTable
POJO( value with getters and setters,also
generated value)
Office.java
package com.infidata.modal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="officeinfo")
public class Office {
#Id
private int sno;
private String batchno;
#ManyToOne
#JoinColumn(name = "id" )
private MyTable myTable;
private String fees;
private String reciptno;
private String trainer;
public Office() {
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
public String getBatchno() {
return batchno;
}
public void setBatchno(String batchno) {
this.batchno = batchno;
}
public String getFees() {
return fees;
}
public void setFees(String fees) {
this.fees = fees;
}
public String getReciptno() {
return reciptno;
}
public void setReciptno(String reciptno) {
this.reciptno = reciptno;
}
public String getTrainer() {
return trainer;
}
public void setTrainer(String trainer) {
this.trainer = trainer;
}
public Office(String batchno,String fees, String reciptno,String trainer) {
super();
this.batchno = batchno;
this.fees = fees;
this.reciptno = reciptno;
this.trainer=trainer;
}
#Override
public String toString() {
return "Office [sno=" + sno + ", batchno=" + batchno + ",fees=" + fees
+ ", reciptno=" + reciptno + ",trainer=" + trainer + "]";
}
}
MyTable.java
package com.infidata.modal;
#Entity
public class MyTable {
}
Database(name of database is workdemo)
User table(Table name: mytable)
CREATE TABLE `mytable`
( `id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`mobile` varchar(10) NOT NULL,
`email` varchar(45) NOT NULL,
`college` varchar(45) NOT NULL,
`branch` varchar(45) NOT NULL,
`semester` varchar(45) NOT NULL,
`address` varchar(105) NOT NULL,
`internship` varchar(45) NOT NULL,
`batch` varchar(45) NOT NULL,
`startdate` varchar(45) NOT NULL,
`enddate` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci
Office table(Table name:office)
CREATE TABLE `office`
(`sno` int(11) NOT NULL AUTO_INCREMENT,
`batchno` varchar(45) NOT NULL,
`id` int(11) NOT NULL,
`fees` varchar(45) NOT NULL,
`reciptno` varchar(45) NOT NULL,
PRIMARY KEY (`sno`),
KEY `id_idx` (`id`),
CONSTRAINT `id` FOREIGN KEY (`id`) REFERENCES `mytable` (`id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
The id(foreign key) in office table should be autoincremented with reference to student id column attribute
The problem is how you defined the entity class :
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
When you use JPA, you must specify the target entity of the relationship, not the field from database.
Your definition just tells the hibernate to generate an int value which will not correspond to a real entity.
It should be something like this:
#ManyToOne
#JoinColumn(name = "id" )
private User user;
Your office object will be
#Entity
#Table(name = "officeinfo")
public class Office {
#Id
private int sno;
private String batchno;
#ManyToOne
#JoinColumn(name = "id")
private User user;
private String fees;
private String reciptno;
private String trainer;
// getters and setters;
}
Please make sure that #Id is only on sno and you don't have on another fields, otherwise it will fail with composite key exception. Please remove id from your object, it is the foreign key to User and it is handled by:
#ManyToOne
#JoinColumn(name = "id")
private User user;

ServiceStack ORMLite not populating results from MySQL

I'm new to ORMLite in ServiceStack. I'm trying to query an existing MySQL database. I've created this POCO to correspond to my table layout in MySQL:
[Alias("checks")]
public class Check
{
[AutoIncrement]
[PrimaryKey]
public long check_id { get; set; }
public long room_state_id { get; set; }
public DateTime? entry_stamp { get; set; }
public int student_id { get; set; }
public string reason { get; set; }
public string comments { get; set; }
public long check_type_id { get; set; }
public DateTime? check_dt { get; set; }
public byte grace { get; set; }
public DateTime curfew_dt { get; set; }
public int excused_by { get; set; }
public string status { get; set; }
public int points { get; set; }
public string check_class { get; set; }
public int leave_id { get; set; }
public DateTime night_of { get; set; }
public DateTime violation_dt { get; set; }
public string excused_reason { get; set; }
public DateTime? excused_dt { get; set; }
public sbyte imported { get; set; }
}
Here's the MySQL table definition
CREATE TABLE checks (
check_id bigint(11) NOT NULL AUTO_INCREMENT,
room_state_id bigint(11) NOT NULL DEFAULT 0,
entry_stamp datetime DEFAULT NULL,
student_id int(11) NOT NULL DEFAULT 0,
reason varchar(60) DEFAULT NULL,
comments text DEFAULT NULL,
check_type_id bigint(20) NOT NULL DEFAULT 0,
check_dt datetime DEFAULT NULL,
grace tinyint(4) UNSIGNED NOT NULL DEFAULT 0,
curfew_dt datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
excused_by int(11) NOT NULL DEFAULT 0,
status char(1) NOT NULL DEFAULT '',
points int(11) NOT NULL DEFAULT 0,
check_class char(2) NOT NULL DEFAULT '',
leave_id int(11) NOT NULL DEFAULT 0,
night_of date NOT NULL DEFAULT '0000-00-00',
violation_dt datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
excused_reason varchar(255) NOT NULL DEFAULT '',
excused_dt datetime DEFAULT '0000-00-00 00:00:00',
imported tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (check_id),
INDEX check_class (check_class),
INDEX check_dt (check_dt),
INDEX check_type_id (check_type_id),
INDEX excused_by (excused_by),
INDEX leave_id (leave_id),
INDEX night_of (night_of),
INDEX status (status),
INDEX student_id (student_id)
)
And I'm trying to get some results using:
public object Get(GetChecks request)
{
return new GetChecksResponse { Results = Db.Select<Check>(q => q.student_id == request.StudentId ) };
}
When I test this, I get a table of results with the right number of rows, but none of the data is populated (all fields in all rows are blank or 0, except for datetimes which have a nonsensical date). How can I find why ORMLite is not populating my POCOs?
UPDATE:
Logging shows a lot of DateTime conversion errors:
2016-01-23 15:35:53.5869|ERROR|OrmLiteWriteCommandExtensions|MySql.Data.Types.MySqlConversionException: Unable to convert MySQL date/time value to System.DateTime
at MySql.Data.Types.MySqlDateTime.GetDateTime()
at MySql.Data.MySqlClient.MySqlDataReader.GetValue(Int32 i)
at MySql.Data.MySqlClient.MySqlDataReader.GetValues(Object[] values)
at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.PopulateWithSqlReader[T](T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader reader, Tuple`3[] indexCache, Object[] values)
If you add logging:
LogManager.LogFactory = new ConsoleLogFactory();
You'll see the error:
ERROR: System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.SByte.Parse(String s, NumberStyles style, NumberFormatInfo info)
at ServiceStack.Text.Common.DeserializeBuiltin`1.<>c.<GetParseFn>b__4_2(String value) in C:\src\ServiceStack.Text\src\ServiceStack.Text\Common\DeserializeBuiltin.cs:line 51
at ServiceStack.OrmLite.OrmLiteConverterExtensions.ConvertNumber(IOrmLiteDialectProvider dialectProvider, Type toIntegerType, Object value) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\IOrmLiteConverter.cs:line 151
at ServiceStack.OrmLite.OrmLiteConverterExtensions.ConvertNumber(IOrmLiteConverter converter, Type toIntegerType, Object value) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\IOrmLiteConverter.cs:line 115
at ServiceStack.OrmLite.Converters.IntegerConverter.FromDbValue(Type fieldType, Object value) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\Converters\IntegerConverters.cs:line 25
at ServiceStack.OrmLite.OrmLiteWriteCommandExtensions.PopulateWithSqlReader[T](T objWithProperties, IOrmLiteDialectProvider dialectProvider, IDataReader reader, Tuple`3[] indexCache, Object[] values) in C:\src\ServiceStack.OrmLite\src\ServiceStack.OrmLite\OrmLiteWriteCommandExtensions.cs:line 343
The issue is that the MySql ADO.NET Provider returns tinyint(1) as a bool so you can resolve the issue by changing it to a bool:
public bool imported { get; set; }

JPA one_to_one relationship not retrieve the auto increment

I have 2 Mysql tables users and empires,
users
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(45) CHARACTER SET utf8 NOT NULL,
`password` varchar(12) CHARACTER SET utf8 NOT NULL,
`country` varchar(25) CHARACTER SET utf8 NOT NULL,
`activated` tinyint(3) unsigned NOT NULL DEFAULT '0',
`activationcode` varchar(45) CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `email_UNIQUE` (`email`),
KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
and empires
CREATE TABLE `empires` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`pid` int(10) unsigned NOT NULL,
`name` varchar(45) CHARACTER SET utf8 NOT NULL,
`notes` varchar(90) CHARACTER SET utf8 NOT NULL,
`world` tinyint(3) unsigned NOT NULL,
`island` smallint(5) DEFAULT NULL,
`population` int(10) unsigned DEFAULT '20',
`gold` decimal(20,0) DEFAULT '500',
`percent` decimal(9,5) DEFAULT '50.00000',
`logo` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`id`,`pid`),
KEY `name` (`name`),
KEY `world` (`world`),
KEY `FK_pid` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
and i have these entities :
package boddooo.entity;
import java.io.Serializable;
import javax.persistence.*;
#Entity
#Table(name="users")
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private int activated=1;
private String activationcode="";
private String country;
private String email;
private String password;
public User(){}
public User(int id,String email,String password,String country) {
this.id=id;
this.email=email;
this.password=password;
this.country=country;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public int getActivated() {
return this.activated;
}
public void setActivated(int activated) {
this.activated = activated;
}
public String getActivationcode() {
return this.activationcode;
}
public void setActivationcode(String activationcode) {
this.activationcode = activationcode;
}
public String getCountry() {
return this.country;
}
public void setCountry(String country) {
this.country = country;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
and
package boddooo.entity;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
#Entity
#Table(name="empires")
#NamedQuery(name="Empire.findAll", query="SELECT e FROM Empire e")
public class Empire implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private int pid;
private BigDecimal gold=BigDecimal.valueOf(500);
private String logo="";
private String name;
private String notes;
private BigDecimal percent=BigDecimal.valueOf(50.0000);
private int population=10;
private int world;
private int island;
#OneToOne
#PrimaryKeyJoinColumn(name="pid")
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Empire(){}
public Empire(int id,String name,String logo,String notes,int world) {
this.id=id;
this.name=name;
this.logo=logo;
this.notes=notes;
this.world=world;
}
public int getPid() {
return pid;
}
public void setPid(int pid){
this.pid=pid;
}
public int getWorld() {
return world;
}
public void setWorld(int world) {
this.world = world;
}
public int getIsland() {
return island;
}
public void setIsland(int island) {
this.island = island;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public BigDecimal getGold() {
return this.gold;
}
public void setGold(BigDecimal gold) {
this.gold = gold;
}
public String getLogo() {
return this.logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getNotes() {
return this.notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public BigDecimal getPercent() {
return this.percent;
}
public void setPercent(BigDecimal percent) {
this.percent = percent;
}
public int getPopulation() {
return this.population;
}
public void setPopulation(int population) {
this.population = population;
}
}
and this function to insert the new objets to the database
public void createUser() throws NamingException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException{
Context icontext=new InitialContext();
ut=(UserTransaction)icontext.lookup("java:comp/UserTransaction");
ut.begin();
User user=new User();
user.setEmail(email);
user.setPassword(password);
user.setCountry(country);
em.persist(user);
Empire emp=new Empire();
emp.setName(empirename);
emp.setNotes(empirenotes);
emp.setLogo(empirelogo);
emp.setWorld(worldid);
emp.setUser(user);
em.persist(emp);
ut.commit();
}
this is one to one relationship which
empires.pid=users.id
but when i call this method it insert users and empires but the pid field in empires has 0 value instead of the auto increment value.
am i miss something? please help
#PrimaryKeyJoinColumn indicates that the field used is this entities primary key, and as such is effectively read-only. This is mostly used when you have an entity that spans multiple tables.
#JoinColumn is what you should be using as it indicates the specified column is a traditional foreign key and that you want the target value to be used to set this field.
#OneToOne
#JoinColumn(name="pid")
private User user;
You should use #JoinColumn(name="fk_id") along with #OneToOne. More details at JSR 317: JavaTM Persistence API, Version 2.0

LINQ: Specified cast is not valid occurs intermittedly

I have an application that has started throwing "Specified cast is not valid" exceptions occassionally. I cannot recreate this error consistently and it is driving me and my users crazy.
Offending code:
public Complaint GetComplaintById(int Id)
{
Complaint complaint = (from c in _context.cts_complaints
join ud in _context.cts_user_details on c.CreatedBy equals ud.UserId
where c.Id == Id
select new Complaint
{
Id = c.Id,
CompanyId = c.CompanyId,
ComplaintTypeId = c.ComplaintTypeId,
CategoryId = c.CategoryId,
ReportCategoryId = c.ReportCategoryId,
ParentId = c.ParentId,
LanguageId = c.LanguageId,
AreaId = c.AreaId,
Title = c.Title,
Description = c.Description,
ResponseDue = c.ResponseDue,
DateReceived = c.DateReceived,
FPSCNumber = c.FPSCNumber,
FPSCRepresentative = c.FPSCRepresentative,
ContactMethodId = c.ContactMethodId,
ContactedBy = c.ContactedBy,
CreatedDate = c.CreatedDate,
CreatedBy = c.CreatedBy,
CreatedByName = ud.Name,
Status = c.Status,
AttachmentsArchived = c.AttachmentsArchived,
Timestamp = c.Timestamp,
}).FirstOrDefault();
complaint.Users = this.GetUsersByComplaintId(Id);
return complaint;
}
Stack Trace:
Specified cast is not valid.
at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult)
at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries)
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at ComplaintTracking.Business.Data.SqlComplaintRepository.GetComplaintById(Int32 Id) in C:\SourceCode2010\ComplaintTracking\Service Pack\1.0 ComplaintTracking\ComplaintTracking.Business\Data\SqlComplaintRepository.cs:line 20
at ComplaintTracking.Business.Managers.ComplaintManager.GetComplaintById(Int32 Id) in C:\SourceCode2010\ComplaintTracking\Service Pack\1.0 ComplaintTracking\ComplaintTracking.Business\Managers\ComplaintManager.cs:line 33
at ComplaintTracking.Web.UserControls.ComplaintViews.ResolveViewPresenter.Init() in C:\SourceCode2010\ComplaintTracking\Service Pack\1.0 ComplaintTracking\ComplaintTracking.Web\UserControls\ComplaintViews\ResolveViewPresenter.cs:line 39
at ComplaintTracking.Web.Library.BaseUserControl`2.OnLoad(EventArgs e) in C:\SourceCode2010\ComplaintTracking\Service Pack\1.0 ComplaintTracking\ComplaintTracking.Web\Library\BaseUserControl.cs:line 56
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Update:
I am attempting to make use of the Repository pattern. I have a LINQ 2 SQL ORM object called cts_complaints which is a 1-1 mapping from my SQL Server table dbo.cts_complaints. Within my application, I have a model called Complaint. My repository is mapping from cts_complaints to Complaint.
[HasSelfValidation]
public class Complaint
{
public Complaint()
{
CreatedBy = System.Threading.Thread.CurrentPrincipal.Identity.Name;
CreatedDate = DateTime.Now;
DateReceived = DateTime.Now;
Users = new List<ComplaintUser>();
}
public int Id { get; internal set; }
public int CompanyId { get; set; }
public int ComplaintTypeId { get; set; }
public int CategoryId { get; set; }
public int ReportCategoryId { get; internal set; }
public int? ParentId { get; set; }
public int LanguageId { get; set; }
public int? AreaId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime ResponseDue { get; set; }
public DateTime DateReceived { get; set; }
public string FPSCNumber { get; set; }
public string FPSCRepresentative { get; set; }
public int ContactMethodId { get; set; }
public string ContactedBy { get; set; }
public int Status { get; set; }
public bool AttachmentsArchived { get; set; }
public DateTime CreatedDate { get; internal set; }
public string CreatedBy { get; internal set; }
public string CreatedByName { get; set; }
public byte[] Timestamp { get; internal set; }
public List<ComplaintUser> Users { get; internal set; }
[SelfValidation()]
public void ValidateUsers(ValidationResults results)
{
//if id is 0 it's new. There must be user
if (Users.Count==0)
results.AddResult(new ValidationResult("You must assign at least one user.", this, "Users", "", null));
}
}
cts_complaints:
CREATE TABLE [dbo].[cts_complaint](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CompanyId] [int] NOT NULL,
[ComplaintTypeId] [int] NOT NULL,
[CategoryId] [int] NOT NULL,
[ReportCategoryId] [int] NOT NULL,
[ParentId] [int] NULL,
[LanguageId] [int] NOT NULL,
[AreaId] [int] NULL,
[Title] [nvarchar](50) NOT NULL,
[Description] [nvarchar](max) NOT NULL,
[ResponseDue] [datetime] NOT NULL,
[DateReceived] [datetime] NOT NULL,
[FPSCNumber] [nvarchar](50) NOT NULL,
[FPSCRepresentative] [nvarchar](50) NOT NULL,
[ContactMethodId] [int] NOT NULL,
[ContactedBy] [nvarchar](50) NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[CreatedBy] [nvarchar](50) NOT NULL,
[Status] [int] NOT NULL,
[AttachmentsArchived] [bit] NOT NULL,
[Timestamp] [timestamp] NOT NULL,
CONSTRAINT [PK_cts_complaint] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
cts_user_details:
CREATE TABLE [dbo].[cts_user_detail](
[UserId] [nvarchar](50) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Email] [nvarchar](255) NOT NULL,
[ManagerEmail] [nvarchar](255) NOT NULL,
[Role] [nvarchar](15) NOT NULL,
[Timestamp] [timestamp] NOT NULL,
CONSTRAINT [PK_cts_user_detail_1] PRIMARY KEY CLUSTERED
(
[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I had the same error and the problem also occurred intermittently.
The cause was a type mismatch between the column type in the database and the field type in the .dbml file
So perhaps check that the types in the auto-generated linq2sql classes (i.e. cts_complaints, not the model class Complaint which I assume you coded yourself) match the types in the database.
(Details for my specific case: In the linq2sql .dbml file there was a field with type double but in the database the column was datetime - not sure how that happened - maybe originally the DB column and .dbml field had the same type and then someone change the type in the DB without re-generating the .dbml file).
Error : Cast is invalid (While trying to load data into datagrid from entity using LINQ)
Cause : Data type is different in mapping entities and SQL server table.
Example : In my case I was using an int in the Entity class and a bigint in the DB, that's why I was getting the error.

Hibernate error: Could not determine type for: com.mysql.jdbc.Blob

I'm working on a project with Hibernate and MySQL. In one of my model objects, I declared a property "image" whose type is Blob, and I used com.mysql.jdbc.Blob. But when I ran that program, an error occurred: org.hibernate.MappingException: Could not determine type for: com.mysql.jdbc.Blob, at table: SPOT, for columns: [org.hibernate.mapping.Column(image)].
Here is source code of data model:
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "SPOT", catalog = "ar", uniqueConstraints = #UniqueConstraint(columnNames = "name"))
#XmlRootElement(name = "spot")
public class Spot extends BaseIdObject {
private Double axisX;
private Double axisY;
private String address;
private String spotType;
private String description;
private String phoneNumber;
private String website;
private Blob image;
#Column(name = "axis_x", precision = 22, scale = 0)
#NotNull
public Double getAxisX() {
return this.axisX;
}
public void setAxisX(Double axisX) {
this.axisX = axisX;
}
#Column(name = "axis_y", precision = 22, scale = 0)
#NotNull
public Double getAxisY() {
return this.axisY;
}
public void setAxisY(Double axisY) {
this.axisY = axisY;
}
#Column(name = "address", length = 200)
#NotNull
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "spot_type", length = 50)
#NotNull
public String getSpotType() {
return this.spotType;
}
public void setSpotType(String spotType) {
this.spotType = spotType;
}
#Column(name = "description", length = 2000)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "phone_number", length = 30)
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
}
And here is the corresponding DDL of table SPOT:
DROP TABLE IF EXISTS `spot`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `spot` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(200) DEFAULT NULL,
`AXIS_X` double NOT NULL,
`AXIS_Y` double NOT NULL,
`ADDRESS` varchar(200) DEFAULT NULL,
`SPOT_TYPE` varchar(50) NOT NULL,
`DESCRIPTION` varchar(2000) DEFAULT NULL,
`PHONE_NUMBER` varchar(30) DEFAULT NULL,
`WEBSITE` varchar(200) DEFAULT NULL,
`IMAGE` blob,
PRIMARY KEY (`ID`),
UNIQUE KEY `SPOT_ID_UNIQUE` (`ID`),
UNIQUE KEY `SPOT_NAME_UNIQUE` (`NAME`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = #saved_cs_client */;
I searched on Internet and found a suggestion of using java.sql.Blob. But when I changed to that type, another error occurred, because in my program, I did some processes with XML on that model object, so it cannot handle the interface java.sql.Blob. So what I have to do to keep the data type com.mysql.jdbc.Blob and the program still run normally with Hibernate? Thank you so much.
I'd say that it's not right to depend on the implementation details for the JDBC driver. I would review your dependency, and try to make it a soft dependency. If you really need to keep this hard dependency, you'll need to implement an UserType capable of handling com.mysql.jdbc.Blob. I don't know the details about this implementation, but you can extend Hibernate's BlobType as MySQLBlobType, and annotate your model property with #Type annotation, specifying this MySQLBlobType:
https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/main/java/org/hibernate/type/BlobType.java
https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/test/java/org/hibernate/test/annotations/type/Dvd.java