How to make new mono with DTO from mono and flux in spring reactive webflux - mono

Here I try to make call from database and combine into new mono from different mono and flux.
public Mono<ListMovieWithKomenDTO> fetchMovieAndKomen(Integer movieId){
Mono<Movie> movie = findById(movieId).subscribeOn(Schedulers.elastic());
Flux<MovieKomen> movieKomen = getKomenByMovieId(movieId).subscribeOn(Schedulers.elastic());
return Mono.zip(movie, movieKomen.collectList(), movieMovieKomenDTOBiFunction);
}
private BiFunction<Movie, List<MovieKomen>, ListMovieWithKomenDTO> movieMovieKomenDTOBiFunction = (x1, x2) -> ListMovieWithKomenDTO.builder()
// .age(x1.getAge())
.id(x1.getId())
.name(x1.getName())
.status(x1.getStatus())
.detail(x1.getDetail())
.url(x1.getUrl())
.movieKomen(x2).build();
In here I make db call twice for header ( like movie ) and detail ( like movie comment ) to separate them. After I make retrieve two different data, I want to join into new mono data based on flux data and mono. to make them into one data, I make DTO to put together from movie table and comment table but it failed. I assume that errors from mono.zip to get data into one new mono.
Here the error from debug console
java.lang.IllegalArgumentException: Cannot encode parameter of type org.springframework.r2dbc.core.Parameter
at io.r2dbc.postgresql.ExtendedQueryPostgresqlStatement.bind(ExtendedQueryPostgresqlStatement.java:89) ~[r2dbc-postgresql-0.8.10.RELEASE.jar:0.8.10.RELEASE]
Thank you

Problem is in my repository I used
public interface MovieKomenRepository extends ReactiveCrudRepository<MovieKomen,Integer> {
#Query("select * from m_movie_komen where m_movie_id = $1")
Flux<MovieKomen> findByMovieId(int movie_id);
}
in above example, I used $1 for the param in query. But when I change my code like bottom. It works like a charm.
public interface MovieKomenRepository extends ReactiveCrudRepository<MovieKomen,Integer> {
#Query("select * from m_movie_komen where m_movie_id = :movie")
Flux<MovieKomen> findByMovieId(#Param("movie") int movie_id);
}
so if someone want to use my service code is fine but careful in repository. we should not used '$1' instead ':movie'. so the problem not in service or mono/flux. but in my repository
Thank you.

Related

RepoDb cannot find mapping configuration

I'm trying to use RepoDb to query the contents of a table (in an existing Sql Server database), but all my attempts result in an InvalidOperationException (There are no 'contructor parameter' and/or 'property member' bindings found between the resultset of the data reader and the type 'MyType').
The query I'm using looks like the following:
public Task<ICollection<MyType>> GetAllAsync()
{
var result = new List<MyType>();
using (var db = new SqlConnection(connectionString).EnsureOpen())
{
result = (await db.ExecuteQueryAsync<MyType>("select * from mytype")).ToList();
}
return result;
}
I'm trying to run this via a unit test, similar to the following:
[Test]
public async Task MyTypeFetcher_returns_all()
{
SqlServerBootstrap.Initialize();
var sut = new MyTypeFetcher("connection string");
var actual = await sut.GetAllAsync();
Assert.IsNotNull(actual);
}
The Entity I'm trying to map to matches the database table (i.e. class name and table name are the same, property names and table column names also match).
I've also tried:
putting annotations on the class I am trying to map to (both at the class level and the property level)
using the ClassMapper to map the class to the db table
using the FluentMapper to map the entire class (i.e. entity-table, all columns, identity, primary)
putting all mappings into a static class which holds all mapping and configuration and calling that in the test
providing mapping information directly in the test via both ClassMapper and FluentMapper
From the error message it seems like RepoDb cannot find the mappings I'm providing. Unfortunately I have no idea how to go about fixing this. I've been through the documentation and the sample tutorials, but I haven't been able to find anything of use. Most of them don't seem to need any mapping configuration (similar to what you would expect when using Dapper). What am I missing, and how can I fix this?

beego QueryTable table name: `cpes` not exists

I have this pice of code in beego:
o := orm.NewOrm()
qs := o.QueryTable("cpes")
and I now that beego connects well with the database, and the database have the 'cpes' table, but I keep getting an error becouse beego don't find the table.
¿How can I debug this further?
You must define model Cpes and register model 'cpes'.
Like:
type Cpes struct {
Id int
}
func (u *Cpes) TableName() string {
// db table name
return "cpes"
}
func init() {
orm.RegisterModel(new(Cpes))
}
I had the same problem. In my case, it was because I didn't register the model.
orm.RegisterModel(new(Member), new(Bank), new(Queue), new(Payment))
Make sure you registered all your models with beego.
The error message should have been more explicit though
I had the same problem a few weeks ago. The answer is in how Beego is translating the table name in the ORM.
The quick fix is to use
qs := o.QueryTable(new(cpes))
Where cpes is the model struct.
If you want to see this in action or this solution does not work for you try using the bee generate api command on your database. This will give you the models in a pre-made fashion as well as a bunch of code examples on how to use them.
Best of luck!

executing a sql code for creating a table and database in zend framework

I wrote a sql script and in it I created a table ;
Now I need to know ,how I can execute this script? (with which codes?)
And I have another question : where? where I must write this codes?(which folder in zend project?)
if it is possible for you please explain with an example.thanks
Creating tables in the database
Zend Framework is not supposed to be the one creating the tables, thus, my suggestion is to run those scripts in other environment.
The fastest one is, probably, the very own SQL shell, but you can use another software such as MySQLWorkbench if you are using MySQL.
Once the tables are created, the access to the tables is made this way:
Introduction
When you are using Zend Framework, you are making use of the MVC pattern. I suggest you to read what is that: Wikipedia MVC
If you read the Wikipedia link, you probably know now that the acess to the database is going to be made by the model.
Thus, if you followed the recommended project structure that Zend provides you will have a models folder under your application folder. There, you are supposed to implement the classes that will make access to the DB.
But well... you now know where to locate those classes but you will ask me: how? It's easy if you know where to search. ZF provides an abstract class called Zend_Db_Table_Abstract that has all the methods that will make your life easier talking about interaction with your database's tables. This is the class that your classes should implement.
Example
Let's suppose you've got a page in your website in which you want to show to the user a list of products of your local store. You have a table in your database called "products" in which you have all the useful information such us name, price and availability.
You will have a controller with an action called indexAction() or listAction() this action is prepared to send the data to your view and will look like:
class Store_ProductsController extends Zend_Controller_Action {
public function indexAction(){
//TODO: Get data from the DataBase into $products variable
$this->view->products = $products;
}
}
And your view file will that that products variable and do sutff with it.
But now comes the magic, you will have a class that will access to the database as I've said, it'll be like:
class Model_Store_Products extends Zend_Db_Table_Abstract{
protected $_name = 'products';
public function getAllProducts(){
$select = $this->$select()
->from(array('P'=>$this->_name),
array('id', 'name', 'price', availability));
$productsArray = $this->fetchAll($select);
return $productsArray;
}
}
And ta-da, you have your array of products ready to be used by the controller:
class Store_ProductsController extends Zend_Controller_Action {
public function indexAction(){
$model = new Model_Store_Products();
$products = $model->getAllProducts();
$this->view->products = $products;
}
}
It can be said that, since fetchAll is public function, and our select does basically nothing but set which columns do we want (it doesn't even have a where clause), in this case, it would be easier to call the fetchAll directly from the controller with no where and it will recover the whole table (all columns):
class Store_ProductsController extends Zend_Controller_Action {
public function indexAction(){
$model = new Model_Store_Products();
$products = $model->fetchAll();
$this->view->products = $products;
}
}
Thus, our function in the model is not even needed.
This is the basic information of how to access to the database using Zend Framework. Further information of how to create the Zend_Db_Table_Select object can be found here.
I hope this helps.

Auto generated linq class is empty?

This is a continuation of my previous question: Could not find an implementation of the query pattern
I'm trying to insert a new 'Inschrijving' into my database. I try this with the following code:
[OperationContract]
public void insertInschrijving(Inschrijvingen inschrijving)
{
var context = new DataClassesDataContext();
context.Inschrijvingens.InsertOnSubmit(inschrijving);
dc.SubmitChanges();
}
But the context.Inschrijvingens.InsertOnSubmit(inschrijving); gives me the following error:
cannot convert from 'OndernemersAward.Web.Service.Inschrijvingen' to 'OndernemersAward.Web.Inschrijvingen'
I call the method in my main page:
Inschrijvingen1Client client = new Inschrijvingen1Client();
Inschrijvingen i = new Inschrijvingen();
client.insertInschrijvingCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_insertInschrijvingCompleted);
client.insertInschrijvingAsync(i);
But as you can see there appears to be something wrong with my Inschrijvingen class, which is auto generated by LINQ. (Auto generated class can be found here: http://pastebin.com/QKuAAKgV)
I'm not entirely sure what is causing this, but I assume it has something to do with the auto generated class not being correct?
Thank you for your time,
Thomas
The problem is that you've got two Inschrijvingen classes - one in the OndernemersAward.Web.Service namespace, and one in the OndernemersAward.Web namespace.
You either need to change the codebase so that you've only got one class, or you need to convert from one type to the other.

How do I wrap an EF 4.1 DbContext in a repository?

All,
I have a requirement to hide my EF implementation behind a Repository. My simple question: Is there a way to execute a 'find' across both a DbSet AND the DbSet.Local without having to deal with them both.
For example - I have standard repository implementation with Add/Update/Remove/FindById. I break the generic pattern by adding a FindByName method (for demo purposes only :). This gives me the following code:
Client App:
ProductCategoryRepository categoryRepository = new ProductCategoryRepository();
categoryRepository.Add(new ProductCategory { Name = "N" });
var category1 = categoryRepository.FindByName("N");
Implementation
public ProductCategory FindByName(string s)
{
// Assume name is unique for demo
return _legoContext.Categories.Where(c => c.Name == s).SingleOrDefault();
}
In this example, category1 is null.
However, if I implement the FindByName method as:
public ProductCategory FindByName(string s)
{
var t = _legoContext.Categories.Local.Where(c => c.Name == s).SingleOrDefault();
if (t == null)
{
t = _legoContext.Categories.Where(c => c.Name == s).SingleOrDefault();
}
return t;
}
In this case, I get what I expect when querying against both a new entry and one that is only in the database. But this presents a few issues that I am confused over:
1) I would assume (as a user of the repository) that cat2 below is not found. But it is found, and the great part is that cat2.Name is "Goober".
ProductCategoryRepository categoryRepository = new ProductCategoryRepository();
var cat = categoryRepository.FindByName("Technic");
cat.Name = "Goober";
var cat2 = categoryRepository.FindByName("Technic");
2) I would like to return a generic IQueryable from my repository.
It just seems like a lot of work to wrap the calls to the DbSet in a repository. Typically, this means that I've screwed something up. I'd appreciate any insight.
With older versions of EF you had very complicated situations that could arise quite fast due to the required references. In this version I would recomend not exposing IQueryable but ICollections or ILists. This will contain EF in your repository and create a good seperation.
Edit: furthermore, by sending back ICollection IEnumerable or IList you are restraining and controlling the queries being sent to the database. This will also allow you to fine tune and maintain the system with greater ease. By exposing IQueriable, you are exposing yourself to side affects which occur when people add more to the query, .Take() or .Where ... .SelectMany, EF will see these additions and will generate sql to reflect these uncontrolled queries. Not confining the queries can result in queries getting executed from the UI and is more complicated tests and maintenance issues in the long run.
since the point of the repository pattern is to be able to swap them out at will. the details of DbSets should be completly hidden.
I think that you're on a good path. The only thing I probaly ask my self is :
Is the context long lived? if not then do not worry about querying Local. An object that has been Inserted / Deleted should only be accessible once it has been comitted.
if this is a long lived context and you need access to deleted and inserted objects then querying the Local is a good idea, but as you've pointed out, you may run into difficulties at some point.