I found a strange query implemented in my project, when I debug and inspect the persistance.query Object just before it call getResultList() method, the queryString I found is :
FROM AuthorityTbl a WHERE bw_and(a.setupFiltersIn, :setupFiltersIn) <> 0
This query is working fine and fetching all data from authority table where setupFiltersIn = :setupFiltersIn.
I am not able to understand yet what is bw_and in this query syntax.
Could anyone have any idea?
I am using sqlServer2014 and direct query with bw_and is not acceptable by sqlServer.
In My application below class is used which register bw_and as bitwise operator
public class ExtendedMSSQLServerDialect extends SQLServerDialect {
public ExtendedMSSQLServerDialect() {
super();
registerFunction("bw_and", new BitwiseSQLFunction(BitwiseSQLOperator.AND, "bw_and"));
registerFunction("bw_or", new BitwiseSQLFunction(BitwiseSQLOperator.OR, "bw_or"));
registerFunction("cast_text_to_varchar_of_length", new CastTextToVarcharSQLFunction("cast_text_to_varchar_of_length"));
}
}
Related
I am trying to write a base class for CRUD operations for "typeorm": "~0.2.45" under "#nestjs/typeorm": "~8.0.3" using node v14.19.3.
The base class looks like this:
export class CrudService<T> {
protected repository: Repository<T>;
constructor(repository: Repository<T>) {
this.repository = repository;
}
...
// Minimized code example
async find() {
return this.repository.find({
where: {
created: Between("2022-06-21T14:18:00.000Z", "2022-06-21T14:19:00.000Z")
}
});
}
}
This generates the following SQL query (which is wrong), it seems to use the Between() object as a literal equality comparison.
query failed: SELECT ... FROM `carts` `CartEntity` WHERE `CartEntity`.`created` = ?
-- PARAMETERS: {
"_type":"between",
"_value":[
"2022-06-21T14:18:00.000Z",
"2022-06-21T14:19:00.000Z"
],
"_useParameter":true,
"_multipleParameters":true
}
If I implement the same code inside the CartsEntity service like this:
#Injectable()
export class CartsService extends CrudService<CartEntity> {
constructor(
#InjectRepository(CartsRepository) repository: CartsRepository
) {
super(repository);
}
...
async find() {
return this.repository.find({
where: {
created: Between("2022-06-21T14:18:00.000Z", "2022-06-21T14:19:00.000Z")
}
});
}
It works fine and retrieves the data with valid SQL using BETWEEN on MySql.
I am wondering what is wrong here since I am using the same instance of repository in both code examples. I tried looking at the TypeOrm FindOperator logic but could not pinpoint it.
It turns out that the problem is a difference in the typeorm npm versions I was using.
The CrudEntity described above is inside a private npm using typeorm 0.2.45 as are my microservices extending CrudEntity like the CartEntity above.
Since #nestjs/typeorm is tagged to typeorm 0.2.34 the type was not the same for FindOperator and thus returned as an object condition instead of a FindOperator generating the proper BETWEEN SQL statement.
Basically, make sure all typeorm versions are the same across all your projects sharing code.
I am using Apache Ignite as the back-end data store in a SpringBoot Application.
I have a requirement where I need to get all the entities whose name matches one of the names from a set of names.
Hence i am trying to get it implemented using a #Query configuration and a method named findAllByName(Iterable<String> names)as below:
Here on the Query, I am trying to use the 'IN' clause and want to pass an array of names as an input to the 'IN' clause.
#RepositoryConfig(cacheName = "Category")
public interface CategoryRepository extends IgniteRepository<Category, Long>
{
List<Category> findByName(String name);
#Query("SELECT * FROM Category WHERE name IN ( ? )")
Iterable<Category> findAllByName(Iterable<String> names); // this method always returns empty list .
}
In this the method findAllByName always returns empty list, even when ignite has Categories for which the name field matches the data passed in the query.
I am unable to figure out if there is a problem with the Syntax or the query of the method signature or the parameters.
Please try using String[] names instead for supplying parameters.
UPDATE: I have just checked the source, and we don't have tests for such scenario. It means that you're on uncharted territory even if it is somehow possible to get to work.
Otherwise looks unsupported currently.
I know your question is more specific to Spring Data Ignite feature. However, as an alternate, you can achieve it using the SqlQuery abstraction of Ignite.
You will form your query like this. I have pasted the sample below with custom sql function inSet that you will write. Also, the below tells how this is used in your sql.
IgniteCache<String, MyRecord> cache = this.ignite
.cache(this.environment.getProperty(Cache.CACHE_NAME));
String sql = "from “my-ignite-cache”.MyRecord WHERE
MyRecord.city=? AND inSet(?, MyRecord.flight)"
SqlQuery<String, MyRecord> sqlQuery = new SqlQuery<>(MyRecord.class,
sql);
sqlQuery.setArgs(MyCity, [Flight1, Flight2 ] );
QueryCursor<Entry<String, MyRecord>> resultCursor = cache.query(sqlQuery);
You can iterate the result cursor to do something meaningful from the extracted data.
resultCursor.forEach(e -> {
MyRecord record = e.getValue();
// do something with result
});
Below is the Ignite Custom Sql function which is used in the above Query - this will help in replicating the IN clause feature.
#QuerySqlFunction
public static boolean inSet(List<String> filterParamArgIds, String id) {
return filterParamArgIds.contains(id);
}
And finally, as a reference MyRecord referred above can be defined something like this.
public class MyRecord implements Serializable {
#QuerySqlField(name = "city", index = true)
private String city;
#QuerySqlField(name = "flight", index = true)
private String flight;
}
I am to using the CacheJdbcPojoStoreFactory
I want to have a VARCHAR field in the database which maps to an Enum in Java.
The way I am trying to achieve this is something like the following. I want the application code to work with the enum, but the persistence to use the string so that it is human readable in the database. I do not want to use int values in the database.
This seems to work fine for creating new objects, but not for reading them out. It seems that it tries to set the field directly, and the setter (setSideAsString) is not called. Of course there is no field called sideAsString. Should this work? Any suggestions?
Here is the code excerpt
In some application code I would do something like
trade.setSide(OrderSide.Buy)
And this will persist fine. I can read "Buy" in the side column as a VARCHAR.
In Trade
private OrderSide side; // OrderSide is an enum with Buy,Sell
public OrderSide getSide() {
return side;
}
public void setSide(OrderSide side) {
this.side = side;
}
public String getSideAsString() {
return this.side.name();
}
public void setSideAsString(String s) {
this.side = OrderSide.valueOf(s);
}
Now when configuring the store, I do this
Collection<JdbcTypeField> vals = new ArrayList<>();
vals.add(new JdbcTypeField(Types.VARCHAR, "side", String.class, "sideAsString"));
After a clean start, If I query Trade using Ignite SQL query, and call trade.getSide() it will be null. Other (directly mapped) columns are fine.
Thanks,
Gordon
BinaryMarshaller deserialize only fields which used in query.
Please try to use OptimizedMarshaller:
IgniteConfiguration cfg = new IgniteConfiguration();
...
cfg.setMarshaller(new OptimizedMarshaller());
Here's the ticket for support enum mapping in CacheJdbcPojoStore.
Following line of code gives me an error saying "The underlying connection was closed".
return this.repository.GetQuery<Countries>().Include(g => g.Cities).AsEnumerable().ToList();
But if I remove .Include(g => g.cities) it works fine.
this code is written in one of the operation in my WCF service, and I try to test it using WCF test client. I tried by calling this operation from MVC application also, and the same issue was occurring there too.
Also, i am using generic repository with entity framework
Repository code (only few important extract)
Constructor:
public GenericRepository(DbContext objectContext)
{
if (objectContext == null)
throw new ArgumentNullException("objectContext");
this._dbContext = objectContext;
this._dbContext.Configuration.LazyLoadingEnabled = false;
this._dbContext.Configuration.ProxyCreationEnabled = false;
}
GetQuery method:
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
var entityName = GetEntityName<TEntity>();
return ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName);
}
Attempt#1
Created following overloads in repository code:
public IQueryable<TEntity> GetQuery<TEntity>(params string[] includes) where TEntity : class
{
var entityName = GetEntityName<TEntity>();
IQueryable<TEntity> query = ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName);
foreach(string include in includes)
{
query = query.Include(include);
}
return query;
}
public IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate, params string[] includes) where TEntity : class
{
return GetQuery<TEntity>(includes).Where(predicate);
}
WCF is now trying to execute following line of code:
return this.repository.GetQuery<Countries>("Cities").AsEnumerable().ToList()
But it still gives the same error of "The underlying connection was closed". I tested it in WCF test client. However, when I debug the repository code it shows the navigation object getting included in result, but the issue seems occurring while trying to pass the output to client (WCF test client, or any other client)
After looking at the code you've now posted, I can conclude that, indeed, your DbContext is being closed at the end of the GetQuery method, and is thus failing when you try to use include. What you might want to do to solve it is to have an optional params variable for the GetQuery method that will take in some properties to be included, and just do the include right in the GetQuery method itself.
I am trying to use following construct
#ApplicationPath("app")
#Path("api/{userid}/model")
public class ModelService
{
#Get
#Path("{modelid: (.*)?}")
public Response removePreProcessor(#PathParam("userid") String sUserId, #PathParam("preprocessorid") String sPreProcessorId)
{
return Response.build();
}
}
I can not access both following REST URL
GET http://localhost:8080/XXXX/app/api/xyz/model
GET http://localhost:8080/XXXX/app/api/xyz/model/123
Let me know what is a wrong I am doing
-Thanks in advance
As I read your question, several things look strange to me but they may be context related.
One thing though seems wrong :
You are using a #PathParam("preprocessorid") but I can't see this param in your path.
Do you have any logs ?