Spring r2dbc composite support - spring-data-r2dbc

It seems Spring r2dbc does not support Composite Primary Key / Embedded Classes.
What other options or work around can be followed in this case?
If i have a table which has Composite Key, then how can I get Flux of objects using partial key, may be the first column?
For e.g
repository.findAllById(String id);
Thanks

You can use annotated queries or you may use the R2dbcEntityTemplate

Related

Which JPA key generator option to choose?

I am new to JPA and databases in general. I was trying to generate entities from tables using JPA tools in Eclipse. There are a number of tables and I am trying to generate entities for all of them at the same time. The JPA tool gives me the following options for Key-generator.
I looked around on Google a bit but could not find much that addresses all the options. What do the options mean?
The JPA specification document provides answers in section 11.1.20, on pages 449 and 450:
The GeneratedValue annotation provides for the specification of
generation strategies for the values of primary keys. The
GeneratedValue annotation may be applied to a primary key property or
field of an entity or mapped superclass in conjunction with the Id
annotation.
The use of the GeneratedValue annotation is only required to be
supported for simple primary keys.
In case you are not familiar with the Id annotation, here is a quick explanation by Vlad Mihalcea from t/his blog post:
The #Id annotation is mandatory for entities, and it must be mapped to
a table column that has a unique constraint. Most often, the #Id
annotation is mapped to the Primary Key table column.
The types of primary key generation are defined by the GenerationType enum:
TABLE, SEQUENCE, IDENTITY, AUTO
The JPA spec gives details on those types as follows:
The TABLE generator type value indicates that the persistence provider
must assign primary keys for the entity using an underlying database
table to ensure uniqueness.
The SEQUENCE and IDENTITY values specify the use of a database
sequence or identity column, respectively. The further specification
of table generators and sequence generators is described in sections
11.1.48 and 11.1.51.
The AUTO value indicates that the persistence provider should pick an
appropriate strategy for the particular database. The AUTO
generation strategy may expect a database resource to exist, or it may
attempt to create one. A vendor may provide documentation on how to
create such resources in the event that it does not support schema
generation or cannot create the schema resource at runtime.
A well-established and recommended strategy is to chose the SEQUENCE strategy, if that is supported by the database management system.
Note well, that strictly speaking, there is no NONE strategy defined in the JPA spec. The corresponding option in the select one menu, depicted in the screenshot, simply expresses that "none" of the four regular types shall be set. This seems to be a fallback to indicate you don’t have chosen your strategy for now. Still, you should pick one from the regular ones.

How to autogenerate a Panache entity

Is it possible to auto generate Panache entities from existing database tables in eclipse/any other environment.?
I am trying out quarkus, and have a database with a number of tables and would like to auto generate the entity code
Panache entities are JPA entities with an extends PanacheEntity or extends PanacheEntityBase at the type decaration site.
You can generate your JPA entities, both Eclipse and ItelliJ IDEA have plugins for that, then add the extends clause.
Be carefull that if you extends PanacheEntity you should use the default id strategy that it provides (an autogenerated Long id), so better extends PanacheEntityBase if you generates from an existing schema.
Panache also provides a repository approach that can be useful if you don't want to update your entity after generation.

What is the difference between spring-data-jpa Repository pattern Vs Querydsl query pattern?

I am devloping Spring MVC + spring-data-jpa + Hibernate example. I'm using simple Repository (by extending JpaRepository<T, ID extends Serializable>) pattern to perform querying on DataSource(DS) and get the result. Even I can write any custom query as per my business needs.
While doing research, I find the "querydsl-sql" API. This API uses plugins and need to use QueryDslPredicateExecutor<T> like (by
extending JpaRepository<T, ID extends Serializable>,
QueryDslPredicateExecutor<T>)
. But on high level it look to me that this API also does the same thing that Repository API does.
Could someone please suggest / guide what is the difference between two methods? One use simple Repository and another uses QueryDslPredicateExecutor
List<Customer> findByCustomerNumberAndCustomerId(Integer customerNumber, Integer customerId);
Querydsl method
#Query("select c from Customer c where c.customerNumber=:customerNumber and c.customerId=:customerId")
List<Customer> findByCustomerNumberAndCustomerId(#Param("customerNumber")
Integer customerNumber, #Param("customerId") Integer customerId);
Your Querydsl method example is actually a spring-data repository method.
The difference is that QueryDsl offers a simple and beautiful way to create dynamic queries to database. I.e. it allows to create SQL "on the fly".
This is useful when for example you need to retrieve a collection of entities with a complex filter. E.g. by name, date, cost etc. And resulting SQL should contain only conditions which specified in filter.
Spring data allows to achieve this without Querydsl using built-in Specifications API but Querydsl way is simpler and even more IDE-friendly.
More on this:
https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

JPA - Compound key vs generated id in Many to many table

I am creating a kind of social network and I have users that can follow other users. So I have an entity like:
#Entity
public class FollowedUser{
#ManyToOne
private User user;
#ManyToOne
private User followedUser;
//more fields
...
}
I cannot have a ManyToMany relationship as I have more fields in my FollowedUser entity. Now, the questions I have are:
Should I use a compound key or a generated id (surrogate key)? I have read the following links (1, 2, 3) about the topic where a surrogate key is suggested, but I don't know if they apply to my concrete case (where my compound key would be composed of two surrogate foreign keys). Also here (4) it says "Composite primary keys typically arise when mapping from legacy databases" so I suppose they are discouraged.
In case I should use a compound key, I don't know if I should use #IdClass (as recommended here 5) or #EmbeddedId (as recommended here 6) or any other option. Although I suppose it doesn't matter.
In case I should use a surrogate key, I don't know how to still make impossible to have the compound candidate key repeated. I have read here (7) about unique indexes but I don't know if it is the correct workaround to that problem.
1. I recommend using surrogate keys. I find it helpful to separate the database identity of a record from it's business identity. If the two concepts are mixed, it may be cumbersome to model them right and to remodel them later. You reference some good answers, so you are probably aware of the major up- and downsides, no need to reiterate them here. One additional point is that you can rely on the surrogate key like UUID to implement equals and hashCode properly. Implementing those for a composite keys to play nicely with both collections and the db can be tricky.
As to your use case, a connection between users can be viewed as an entity of it's own and have a autogenerated surrogate PK. You can enforce the uniqueness of the business key attributes in the DB, see pt.3.
2. AFAIK, deciding between EmbeddedId and IdClass is mostly a matter of taste. I prefer
IdClass, since it avoids having to add navigation when querying id attributes:
... WHERE a.id.attribute = :att with EmbeddedId vs.
... WHERE a.attribute = :att vs. with IdClass
I do not find the argument you link 6 convincing. Composite keys tend to consist of the most characteristic attributes of the entity. To hide them away in a different class because they happen to be used as the DB key seems awkward to me.
3. Unique indexes look like a good way to guarantee uniqueness of a combination of attributes. You may want to read this answers, there is a small example.
If you are not yet working with JPA 2.1, you might want to use unique constraints, as explained here.

Composite DB keys with Entity Framework 4.0

The re-design for a large database at our company makes extensive use of composite primary keys on the database.
Forgetting performance impacts, will this cause any difficulties when working with this db in Entity Framework 4.0? The database structure is unlikely to change and I'm not looking for "philosophical" debate but what are the practical impacts?
According to Jeremy Miller, "Composite key make any kind of Object/Relational mapping and persistance in general harder." but he doesn't really say why. Is this relavent to how Entity Framework 4.0 handles keys?
No, EF4 supports composite keys just fine.
The problem is a table with a surrogate key and composite keys. You can only set a single key on each model; that key can have multiple fields, but you can only have one from the designer standpoint. Not sure about manually editing xml or code only mapping.
You can set a field as an Identity and not a key if you need a composite and surrogate key on the same table. The Identity ( Id ) field won't be used by the ObjectContext or ObjectStateTracker but will increment and be queryable just fine though.
I have had problems with EF4 and composite keys. It doesn't support columns being used as components in more than one key in a join table.
See my previous question Mapping composite foreign keys in a many-many relationship in Entity Framework for more details. The nuts of it is that when you have a join table (describing a many-many relationship) where both of the relationships use a common key, you'll get an error like
Error 3021: Problem in mapping
fragments...: Each of the following
columns in table PageView is mapped to
multiple conceptual side properties:
PageView.Version is mapped to
(PageView_Association.View.Version,
PageView_Association.Page.Version)
The only way around it was to duplicate the column which defeats the purpose of having it there at all.
Good luck!