I am getting an SQL exception
java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'as col_7_0_ from locales offerlocal0_ cross join offers offer2_ inner join offer' at line 1
While calling the repository method
#Query("SELECT DISTINCT new com.greenflamingo.staticplus.model.catalog.dto.OfferGet(ol.root.id,ol.title "
+ ",ol.description,dl.name,ol.root.price,ol.root.currency,ol.root.visible,ol.root.images) "
+ "FROM OfferLocale ol,DescriptorLocale dl "
+ "WHERE ol.root.webfront.id = (:webId) AND ol.culture.languageCode = (:langCode) "
+ "AND dl.culture.languageCode = (:langCode) "
+ "AND ol.root.category = dl.root")
Page<OfferGet> findAllWebfrontLocalized(#Param("webId")int webfrontId,#Param("langCode")String langCode,Pageable pageable );
I have narrowed the issue down to the Collection i am trying to pass to constructor (ol.root.images) . Tried with List (it gave me a constructor missmatch) and with Set (had the same error as shown here)
This is the bean i am using
public class OfferGet implements Serializable{
private static final long serialVersionUID = 6942049862208633335L;
private int id;
private String title;
private String shortDescription;
private String price;
private String category;
private boolean visible;
private List<Image> images;
public OfferGet(String title, String category) {
super();
..........
}
public OfferGet() {
super();
}
public OfferGet(int id, String title, String description
, BigDecimal price
,String currency,
boolean visible) {
.........
}
public OfferGet(int id, String title, String description,String category
, BigDecimal price
,String currency,
boolean visible,
Collection<Image> images) {
..........
}
}
I am using java 11, mariaDb and Springboot 2.0.5
Does anyone know why is this happening and if there is any way around it? Any help would be much appreciated, mustache gracias! :D
It's not possible to create an object with the constructor expression that takes a collection as argument.
The result of a SQL query is always a table.
The reason is that identification variables such that they represent instances, not collections.
Additionally you cannot return root.images you must join the OneToMany relationship and then you no longer have a collection but each attribute.
The result of the query will be cartesian product.
This is a correct query:
#Query("SELECT DISTINCT new com.greenflamingo.staticplus.model.catalog.dto.OfferGet(ol.root.id,ol.title "
+ ",ol.description,dl.name,ol.root.price,ol.root.currency,ol.root.visible, image) "
+ "FROM OfferLocale ol,DescriptorLocale dl "
+ "JOIN ol.root.images image
+ "WHERE ol.root.webfront.id = (:webId) AND ol.culture.languageCode = (:langCode) "
+ "AND dl.culture.languageCode = (:langCode) "
+ "AND ol.root.category = dl.root")
Related
I was trying to get spatial data from Oracle database with Mybatis in Springboot, when I use the function GET_WKT() the returned value is null but they should not be null.
This is the code for query:
#Select("SELECT T.OBJECT_ID," +
"T.STRUCTURE_CODE," +
"T.TYPE," +
"T.NAME," +
"T.LENGTH," +
"T.WIDTH," +
"T.HEIGHT," +
"T.WEIGHT," +
"T.REMARK," +
"dbms_lob.substr(T.GEOM.GET_WKT(),4000) " +
"FROM JZW_BRIDGE_POINT T WHERE T.STRUCTURE_CODE = #{structureCode}")
Bridge getBridgeByStructureCode(#Param("structureCode") String structureCode);
This is the object used to hold the result:
public class Bridge {
private String objectId;
private String structureCode;
private String type;
private String name;
private Double length;
private Double width;
private Double height;
private Double weight;
private String remark;
private Integer isDelete;
private String geom;
getters and setters...
When I use the same SQL in the PL/SQL, it can return a proper result with the WKT returned as a string. I'm using OJDBC 8 and I used OJDBC 6, both of them doesn't work as I intended. Any help is appreciated.
There is no name for the resulting column specified so mybatis does not know what value from the result set should be put to geom column.
By default mybatis maps the column to the property (optionally mapping underscore names to camel case like STRUCTURE_CODE -> structureCode). But you query does not specify the name for the value returned by dbms_lob.substr(T.GEOM.GET_WKT(),4000) expression so it gets some name generated by oracle or jdbc driver and mybatis can't know that it should be put to some column in the result object.
Modify the query and specify the name for the result:
#Select("SELECT T.OBJECT_ID," +
"T.STRUCTURE_CODE," +
"T.TYPE," +
"T.NAME," +
"T.LENGTH," +
"T.WIDTH," +
"T.HEIGHT," +
"T.WEIGHT," +
"T.REMARK," +
"dbms_lob.substr(T.GEOM.GET_WKT(),4000) geom " +
"FROM JZW_BRIDGE_POINT T WHERE T.STRUCTURE_CODE = #{structureCode}")
Bridge getBridgeByStructureCode(#Param("structureCode") String structureCode);
I don't know if this is possible but I am trying to project data queried from JPA repository into a DTO
I have the following query:
#Query(value =
"SELECT crop.id, count(*) as total " +
"FROM xxx.crop_sub_plot " +
"join crop on crop.id = crop_sub_plot.crop_id " +
"join sub_plot on sub_plot.id = crop_sub_plot.sub_plot_id " +
"where sub_plot.enabled = true " +
"group by crop_id " +
"order by total DESC;", nativeQuery = true)
List<CropUsedView> findCropsInUseOrderByDesc();
and the DTO:
public class CropUsedView implements Serializable{
private BigInteger id;
private BigInteger total;
public CropUsedView() {
}
public CropUsedView(BigInteger id, BigInteger total) {
this.id = id;
this.total = total;
}
//getters && setters
I'm getting the error:
No converter found capable of converting from type [java.math.BigInteger] to type [net.xxx.crop.CropUsedView]
I don't really know if this is possible, any suggestion?
EDIT: this is how the data is returning when I run the query on MySql and is how I want to be converted to a DTO:
Your query is returning two values: the id and a count (both can be mapped in a long or BigDecimal). But Hibernate, as it's not mapped directly into an object, is just returning BigDecimal[].
To solve this, you should use a custom mapper: UserType (https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/usertype/UserType.html). This allows you to map whatever response into an object with a manual parsing.
I would like to fetch serveral rows of data from a table.
I have a dao, sql and some parameters.
public static final String SELECT = ""
+ "SELECT NAME, SURNAME, AGE, LEVEL"
+ "FROM MYTABLE "
+ "WHERE "
public static final String CONDITION = ""
+ "SURNAME = :" + PARAM_SURNAME
+ "AND LEVEL = :" + PARAM_LEVEL;
For retrieval of a signle object I would do something like that:
public MyObject getMyThing(
final String surname,
final Integer level) {
final MapSqlParameterSource parameters = new MapSqlParameterSource()
.addValue(PARAM_SURNAME, surname)
.addValue(PARAM_LEVEL, level);
final String query = SELECT + CONDITION;
return myNamedTemplate.query(query, parameters, new MyObjectRowMapper());
}
And it is be just fine. However I would also like to use one SQL to retrieve several objects from databse. I know about the "IN" clause but it is not good enough as its usage will affect performance in the bad way.
What I would want is something that results in a following query:
SELECT STUFF FROM TABLE WHERE
//and the part I am interested in:
(SURNAME = :PARAM_SURNAME
AND LEVEL = :PARAM_LEVEL)
OR
(SURNAME = :PARAM_SURNAME
AND LEVEL = :PARAM_LEVEL)
OR
(SURNAME = :PARAM_SURNAME
AND LEVEL = :PARAM_LEVEL)
//and so on...
So the question:
How can I achieve this using JDBC Named Template in Spring? I cannot figure out how to do parameter mapping. Desired method in DAO could be something like that:
public List<MyObject> getMyThings(
final List<String> surnames,
final List<Integer> levels) {
final MapSqlParameterSource parameters = // magic
final String query = // more magic
return myNamedTemplate.query(query, parameters, new MyObjectRowMapper());
}
I get a ClassCastException when trying to query my JPA entity class. I only want json to show two columns. That is name and address. How do I only show selected columns in JPA? From debugging it has to be the for loop. So List is the object and I need to make the right side an object instead of a list correct?
Entity
#Entity
#Table(name = "Personnel")
public class User implements Serializable {
private String id;
private String name;
private String address;
public User(String id, String name, String address)
{
this.id = id;
this.name = name;
this.address = address;
}
#Id
#Column(name = "name", unique = true, nullable = false)
public String getName() {
return this.name;
}....
//setters getters
Query/Impl
public List<User> getRecords(User ent){
String sql = "select "
+ " usr.name, usr.address "
+ " from User usr"
+ " where usr.id = '1' ";
List<User> records = this.getSession().createQuery(sql).list();
for ( User event : records ) {
System.out.println( "Records (" + event.getName + ") );
}
return records;
}
Update
This is my attempt to declare the result object as List. Does the method have to be an object instead of ?
public List<User> getRecords(User ent){
String sql = "select "
+ " usr.name, usr.address "
+ " from User usr"
+ " where usr.id = '1' ";
Map<String, String> results = new HashMap<String, String>();
List<Object[]> resultList = this.getSession().createQuery(sql).list();
// Place results in map
for (Object[] items: resultList) {
results.put((String)items[0], (String)items[1]);
results.toString();
}
return (List<User>) results;
You can pass a DTO class to the SELECT clause like this:
List<UserDTO> resultList = this.getSession().createQuery("""
select
new my.package.UserDTO(usr.name, usr.address)
from User usr
where usr.id = :userId
""")
.setParameter("userId", userId)
.getResultList();
You should read the complete object:
String sql = " from User usr"
+ " where usr.id = '1' ";
Or declare the result object as List<Object[]>
You can use generic(I assure you are using java 1.5 and above) and and one you get result, you do type check and downcast to desired type.
If You don't want to read the complete object you have to use Criteria and Projection on specific properties.
See this answer it will help
I am running into an issue.
I search for several hours but did not find any anwers.
What I want to do is a sql select, in which the ORDER clause depends on the value of a column (so it changes for every tuples).
I managed to do it via HQL with something like that :
SELECT NEW myDTO(m.id, m.name, " + calculDistance + " AS distance) FROM Table m GROUP BY m.mercId ORDER BY distance ASC
With calculDistance depending of m.latitude and m.longitude
This works fine.
However, my request is much more complicated than that and for reading, update and such reasons, I'd like to do it directly with JPA.
Do you know if this is possible?
Thanks for your help.
EDIT
Here is the part of my table structure (I put only the needed columns):
#Entity
#Table(name = "td_merchant")
#XmlRootElement
#SequenceGenerator(name = "td_merchant_id_seq", sequenceName = "td_merchant_id_seq")
public class Merchant implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(generator = "td_merchant_id_seq", strategy = GenerationType.SEQUENCE)
#Column(name = "merc_id")
private Integer mercId;
#Column(name = "merc_name")
private String mercName;
#Column(name = "merc_latitude")
private Double mercLatitude;
#Column(name = "merc_longitude")
private Double mercLongitude;
...
}
I also faced same issue, i wrote one function which was taking input for order by as well as asc and desc seq.
public List<CompanyName> loadAllCompanies(CompanySortField sortField, boolean ascending) {
String queryString = "select new com.Company(u.name, u.surname, " +
" country.name, country.population, " +
" city.name) from Company u left join u.city as city left join u.country as country " +
" order by " + sortField.getField() + (ascending ? " asc " : " desc ");
return entityManager.createQuery(queryString).getResultList();
}
You can try in this way, only thing is you need to fire another query to find out company sort field.