SQLGrammar error when querying MySql view - mysql

When a run a GET request i get an exception o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'disburseme0_.reason_type' in 'field list' in stack trace even though i have configured the field correctly in the entity class. I have a Spring Boot SOAP interface that is querying a MySql database view. I have assigned one of the unique keys from the parent tables as the view Id in JPA.
Part of my entity class has:
#Entity
#Table(name="disbursement_payload")
public class Disbursement {
#Id
#Column(name="ID")
private long disbursementId;
#Column(name="ReasonType")
private String reasonType;
public long getDisbursementId() {
return disbursementId;
}
public void setDisbursementId(long disbursementId) {
this.disbursementId = disbursementId;
public String getReasonType() {
return reasonType;
}
public void setReasonType(String reasonType) {
this.reasonType = reasonType;
}
I have the view as:
CREATE VIEW disbursement_payload AS (
SELECT
iso_number AS Currency,
trans_desc AS ReasonType,
account_number AS ReceiverParty,
amount AS Amount
FROM m_payment_detail, m_loan_transaction
WHERE m_payment_detail.`id`= m_loan_transaction.`payment_detail_id` AND
m_payment_detail.`payment_type_id`=2
);
Is there something im missing , in the entity or view definition? I have read one of the comments here could not extract ResultSet in hibernate that i might have to explicitly define the parent schemas. Any assistance, greatly appreciated.

do the mapping for db column and class var name based on camelCase conversion basded on underscore _ separated name
you could try using
CREATE VIEW disbursement_payload AS (
SELECT iso_number AS currency
, trans_desc AS reason_type
, account_number AS receiver_rarty
, amount AS amount
FROM m_payment_detail
INNER JOIN m_loan_transaction
ON m_payment_detail.`id`= m_loan_transaction.`payment_detail_id`
AND m_payment_detail.`payment_type_id`=2
);
the view code is SQL code and hibernate see a view as a table, so the conversion of column name is base on the same rules
and a suggestion you should not use (older) implicit join based on where condition you should use (more recent) explici join sintax ..

Related

Using LongListSelector with a Deployed Database

I'm trying to create an app for Windows Phone 8 that displays data in a LongListSelector that's populated from a SQL CE database that's shipped with the app. I think I have the opening and reading from the database functions down, but I can't correctly use LINQ to SQL to group the data for the LLS.
I've got a database class with a table and corresponding columns. I'm using a helper class "KeyedList" to add a public name for the data from msdn sample code:
public class KeyedList<TKey, TItem> : List<TItem>
{
public TKey Key { protected set; get; }
public KeyedList(TKey key, IEnumerable<TItem> items)
: base(items)
{
Key = key;
}
public KeyedList(IGrouping<TKey, TItem> grouping)
: base(grouping)
{
Key = grouping.Key;
}
}
Then I've got my database context:
dB = new DataContext(DataContext.DBConnectionString);
Finally, here's the LINQ to SQL I'm trying to use:
var items =
from item in dB.TableName
orderby dB.ID
group item by dB.Generation into generation
select new <KeyedList<string,Item>(generation);
var allItems = new List<KeyedList<string, Item>>(items)
I've pretty much taken this code from the sample, but I can't get the grouping and ordering to work when creating allItems for binding to the LongListSelector. I keep getting invalid arguments error.
I'm very new at VB programming and appreciate all the help!
I found the issue. When creating the new Keyed list make sure to use the correct key type and item type. The key type will be the type of the data used by group by, and the item type is your DataContext. So in my case db.Generation is a string and the DataContext type is of type Item.

sqlexception index out of bounds with correct sql-statement

i've got an sql statement that works pretty well. but on implementing in my webapp working with play 2.1 i get this error:
javax.persistence.PersistenceException: Query threw SQLException:Column Index out of range, 0 < 1.
i found this question here: Error executing MySQL query via ebean using RawSql
but then i got other exceptions.
i'm trying to get tagged threads that contains a list of tags (same as stack overflow does).
here the sql statement
SELECT t.topic
FROM topic t
WHERE 3 = (SELECT COUNT( DISTINCT ta.id )
FROM topic_tag tt
INNER JOIN tag ta ON ta.id = tt.tag_id
WHERE ta.name IN ('children', 'spain','new')
AND tt.topic_id = t.id )
in play i do this:
RawSql rawSql = RawSqlBuilder.unparsed(sqlString).create();
result = find.setRawSql(rawSql).findList();
then, i got the out of bounds exception. after that i try to set column mappings:
RawSql rawSql = RawSqlBuilder.unparsed(sqlString)
.columnMapping("t.topic","topic")
.columnMapping("t.id","id")
.columnMapping("ta.name","tagList.name")
.columnMapping("ta.id","tagList.id")
.create();
now i get a null pointer exception. probably because ebean can't create a query from that.
here some code from my models:
#Entity
public class Topic extends Model{
#Id
public Long id;
#Required
public String topic;
#ManyToMany
public List<Tag> tagList;
}
#Entity
public class Tag extends Model {
#Id
public long id;
#Required
public String name;
}
after a lot of trying and frustrating i hope that somebody got a hint or a solution for this.
I just wasted few hours with similar problem, I actually managed to solve it by only mapping id field for certain kind of model and selecting lesser amount of fields, other values were automatically loaded after that - So basically, error occurred if I tried to select values like:
.. select e.id, e.name, e.description from exampleTable e .. and use mappings like:
RawSql rawSql = RawSqlBuilder.parse(sql)
// map the sql result columns to bean properties
.columnMapping("e.id", "exampleModel.id")
.columnMapping("e.name", "exampleModel.name")
.columnMapping("e.description", "exampleModel.description")
.create();
When I changed to select only e.id and map:
RawSql rawSql = RawSqlBuilder.parse(sql)
// map the sql result columns to bean properties
.columnMapping("e.id", "exampleModel.id")
.create();
It loaded also e.name and e.description to model values and errors disappeared.
(Of course my own query had several joins and were bit more complicated than this, but basics are the same.)
So to summarize: when this problem occurs, check that you are not loading anything twice (columnMapping), use System.out.println(""); or similar to check which values are already loaded for your model. Remember to also check annotations such as "#JoinColumn" which might load more data under same model - just based on given e.id value. If you dont select and set e.id as columnMapping value, then you might need to list all needed fields separately as .. e.name, e.description ..
Hopefully these findings helps someone out.

Select column from non-generic DbSet?

I want to implement a function that accepts a DbSet (non-generic), a string, and object, and returns DbSet. something like the following pseudu:
public static DbSet Any(DbSet set, string propertyName, objectParameter)
{
var tableName = set.TableName;
var columnName = set.GetColumnNameForProperty(propertyName);
var query = string.Format("SELECT TOP(1) {0} FROM {1} WHERE {0} = {2}",
columnName,
tableName,
objectParameter);
}
I think that SQL query is enough since I'll be able to execute it directly on the Database (context.Database.ExecuteSql).
What I want to do is get the table name from the given DbSet, then the column name in the database.
It is not possible from non generic DbSet but this problem can be easily solved by using:
public static IEnumerable<T> Any(DbSet<T> set, string property, objectParameter)
where T : class
{ ... }
Returning DbSet doesn't make sense because once you query data it is not DbSet anymore.
The bigger problem is getting table name from generic DbSet / ObjectSet because this information is not available from those classes. It is almost impossible to get it at all because it requires accessing non public members of items from MetadataWorkspace.

JPA native query for LONGTEXT field in a MySQL view results in error

I have the following JPA SqlResultSetMapping:
#SqlResultSetMappings({
#SqlResultSetMapping(name="GroupParticipantDTO",
columns={
#ColumnResult(name="gpId"),
#ColumnResult(name="gpRole"),
// #ColumnResult(name="gpRemarks")
}
)
Which is used like this:
StringBuilder sbQuery = new StringBuilder("Select ");
sbQuery.append(" gpId, ");
sbQuery.append(" gpRole, ");
// sbQuery.append(" gpRemarks ");
sbQuery.append(" FROM v_group_participants_with_details ");
Query query = em.createNativeQuery(sbQuery.toString(), "GroupParticipantDTO");
The view is like this:
DROP VIEW IF EXISTS `v_group_participants_with_details`;
CREATE VIEW `v_group_participants_with_details`
AS
SELECT
gp.id AS gpId,
gp.role AS gpRole,
gp.remarks AS gpRemarks
FROM GroupParticipation gp
;
The GroupParticipation table has the remarks column defined as LONGTEXT (I'm using Mysql 5.x)
Now for the problem:
When the remarks field is commented out from the query everything works perfectly, but if I try to include the remarks field in the query, I get the following error:
javax.persistence.PersistenceException: org.hibernate.MappingException:
No Dialect mapping for JDBC type: -1
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException
(AbstractEntityManagerImpl.java:614)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:76)
What gives? How can I get a LONGTEXT column from a native query?
This problem is reported in HHH-1483 and HHH-3892. In short, Hibernate does not know, how to map a LONGVARCHAR column returned by a native query.
This problem is fixed in Hibernate 3.5.0+. For previous versions, a workaround would be to extend the MysqlDialect to register the correct Hibernate Type for a LONGVARCHAR:
import java.sql.Types;
import org.hibernate.Hibernate;
public class MyMySQL5Dialect extends org.hibernate.dialect.MySQL5Dialect {
public MyMySQL5Dialect() {
super();
// register additional hibernate types for default use in scalar sqlquery type auto detection
registerHibernateType(Types.LONGVARCHAR, Hibernate.TEXT.getName());
}
}

LINQ + type tables best practices

Whats the best design pattern to use for LINQ and type tables that exist in SQL.
I have tables in SQL that constrain values to type values, and I want to be able to use this in my C# code as strongly typed values.
My current approach for a 'PackageStatus' type is as follows:
SQL Table
PackageStatusType (int)
desc (varchar)
C# Class - using LINQ
public class PackageStatusType
{
static PackageStatusType()
{
var lookup = (from p in DataProvider.ShipperDB.PackageStatus
select p).ToDictionary(p => p.Desc);
Unknown = lookup["Unknown"];
LabelGenerated = lookup["Label generated"];
ReadyForCollection = lookup["Ready for pickup"];
PickedUp = lookup["Picked up"];
InTransit = lookup["In Transit"];
DeliveryAttempted = lookup["Delivery attempted"];
DeliveredByHand = lookup["By hand"];
DeliveryFailed = lookup["Delivery failed"];
Delivered = lookup["Delivered"];
Voided = lookup["Voided"];
}
public static ShipperDB.Model.PackageStatus Unknown;
public static ShipperDB.Model.PackageStatus LabelGenerated;
public static ShipperDB.Model.PackageStatus ReadyForCollection;
public static ShipperDB.Model.PackageStatus PickedUp;
public static ShipperDB.Model.PackageStatus InTransit;
public static ShipperDB.Model.PackageStatus DeliveryAttempted;
public static ShipperDB.Model.PackageStatus DeliveryFailed;
public static ShipperDB.Model.PackageStatus Delivered;
public static ShipperDB.Model.PackageStatus DeliveredByHand;
public static ShipperDB.Model.PackageStatus Voided;
}
I then can put PackageStatusType.Delivered in my C# code and it will correctly reference the right LINQ entity.
This works fine, but makes me wonder:
a) how can i make this more efficient
b) why doesn't Microsoft seem to provide anything to create strongly typed type tables
c) is my database design even a good one?
d) what is everyone else doing!
thanks!
Linq to SQL allows you to map a string or int column in a database to an enumeration in your C# code. This allows you to let Linq to SQL to map these values for you when you select from the database. In this case, I would change my package status column to be either an int column with the values from the enumeration or a string that represents the values from the enumeration.
In your case, I would have a PackageStatus enumeration with the different values that you specified, and then using the ORM designer or SQLMetal, map that column to that enumeration. The only caveat is that the string values in the column in the database must match the values in the enumeration as Linq to SQL will use Enum.Parse() to map the string values from the database to the enumeration or make sure that the int values in the database match the values from the enumeration.
This is more efficient as you don't even need to map the lookup table at all in the code.
http://msdn.microsoft.com/en-us/library/bb386947.aspx#EnumMapping describes how this works.