I am having trouble figuring out if GCP Datastore supports querying nested properties of an entity.
My use case right now is like so:
Module
-> Application
Module
Application
#Entity
class Module {
Long id;
#Reference
Applicaiton application;
}
#Entity
class Application {
Long id;
String name;
}
I want to try query the module based on its nested Application name. I have tried providing the filter like so without success:
Query<? extends BaseEntity> query = Query.newEntityQueryBuilder()
.setKind("module")
.setFilter(PropertyFilter.eq("application.name", "UserApp"))
.build();
I'm using Springs GCP datastore abstraction through their DatastoreTemplate, but this doesn't seem related given that when I try run the GQL on the GCP console I get no results back either.
SELECT * FROM module WHERE application.name = "UserApp"
Thanks for taking the time to read through this. Any help with this is greatly appreciated!
It looks like you are using a Reference and not an embedded entity. The Application in module is really a key reference to an Application entity. Thus the values of application are not an indexed on the Module entity.
Related
I got a task, to create a basic app with some database handling.
I'm really new at this, the whole spring boot and stuff.
I did all the GET, PUT, POST, DELETE stuff without writing any line of SQL, starts with table creation.
But they asked me to provide the SQL script, how I managed to create the database structure, connections and stuff.
How can I solve this problem?
Add following to spring.jpa.properties
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata
Please refer this article https://www.baeldung.com/spring-data-jpa-generate-db-schema by #baeldung for more detail.
The most simple way to do this is to create in the resources folder a file named schema.sql with all your queries concerning the DDL (tables creation...) and a data.sql if needed where you can add INSERT queries to populate your database.
In the application.properties then you have to add spring.jpa.hibernate.ddl-auto=none to disable the schema creation of JPA and let Spring Boot executes those scripts at startup automatically.
If you want something more powerful, you should try Liquibase or Flyway.
You can used Jpa Like JpaRepository interface. You don't need write any SQL query we use it just used config your data base into Application.Property like database type
Your user name and password
public interface UserRepository extends CrudRepository<User, Integer> {}
when execute this code you can used create user , get find all user , find user by id , delete user and update user
and used #Entity annotaion into Entity class
the Entity class Represent Table into your database
#Entity
#Table(name="user")
public class User{
#Colume(name="id")
private Long id;
#Colume(name="name")
private String name;
//getter and setter here
}
when run this class your data base contract User table with id and
name
this link create spring boot application with database
https://spring.io/guides/gs/accessing-data-mysql/
I'm upgrading a JHipster app written using Hibernate4 to Hibernate5.
The Hibernate4 version has been running in production just fine, but I want to upgrade to a much newer version of Spring Boot which means also Hibernate5.
I'm running into some query issues with Hibernate5 and would appreciate some extra eyes to confirm I've got the tables updated properly with correct Hibernate syntax.
// base Entity
#Entity
#Table(name = "jhi_user")
public class User extends AbstractAuditingEntity implements Serializable {
// default JHipster generated attributes
}
// additional User attributes
#Entity
public class Foo extends User {
// some extra attributes, but no "Id" field since it extends User
private String attribute1;
private String attribute2;
}
// another Entity inheriting from Foo
#Entity
public class Bar extends Foo {
private String attribute3;
private String attribute4;
}
When I'm trying to use the UserRepository to find the User account for authentication, I'm getting a lot of grief from Hibernate. I think this relationship structure is no longer valid for Hibernate5, but not sure what to do.
Update: I did locate this article - https://www.jhipster.tech/tips/022_tip_registering_user_with_additional_information.html
Update #2: The author of that article actually put a sample project together which I'm linking for anyone else finding themselves down this rabbit hole.
https://github.com/Paul-Etienne/jhipster-userextra-example - however it's missing a few key pieces (IMHO) such as updating the UserExtra.phone field. which repository do I find the User from to reference the other?
Update #3: Although I know of #MappedSuperClass, it's not an option in my specific case, as I'm working with a database that already persists the base object's data.
Update #4: If versions are a "thing" here, I'm running Spring Boot 2.2.7.RELEASE and Hibernate 5.4.15.Final
I'm experimenting down this path, but it's really causing a lot of refactoring pain, so I'll look at any other viable option.
I am using spring-cloud-gcp-starter-data-firestore for accessing Google Cloud Firestore in my Java Spring application.
Currently, my entity looks like this:
public class Subscription {
public String userId;
public String companyId;
// other properties
}
However, I obtain the userId and companyId via a reactor.core.publisher.Mono in org.springframework.security.core.context.ReactiveSecurityContextHolder.
How can I persist both properties which are nested inside Monos without resorting to Mono#block?
I am now using Mono#zipWith to combine both Monos. Then I am creating the entity inside Mono#flatMap.
service.getCompanyId()
.zipWith(service.getUserId())
.flatMap(objects -> createEntity(objects.getT1(), objects.getT2()))
I suggest following the tutorial in the Google codelab.
Here you can find that Firestore can be in Datastore mode which makes the previous tutorial suitable for you.
I'm going to start a project of a REST application managed with Spring and with Hibernate for my model.
I know that Spring allows you to get Java object from the HTTP Request (with #Consumes(JSON) annotation). Is there any conflict if this Java object is also a Hibernate entities? And is nested object working (like #ManyToOne relation)?
Maven dependency
The first thing you need to do is to set up the following Hibernate Types Maven dependency in your project pom.xml configuration file:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
Domain model
Now, if you are using PostgreSQL, you need to use the JsonType from Hibernate Types.
In order to use it in your entities, you will have to declare it on either class level or in a package-info.java package-level descriptor, like this:
#TypeDef(name = "json", typeClass = JsonType.class)
And, the entity mapping will look like this:
#Type(type = "json")
#Column(columnDefinition = "json")
private Location location;
If you're using Hibernate 5 or later, then the JSON type is registered automatically by the Postgre92Dialect.
Otherwise, you need to register it yourself:
public class PostgreSQLDialect extends PostgreSQL91Dialect {
public PostgreSQL92Dialect() {
super();
this.registerColumnType( Types.JAVA_OBJECT, "json" );
}
}
The JsonType works with Oracle, SQL Server, PostgreSQL, MySQL, and H2 as well. Check out the project page for more details about how you can map JSON column types on various relational database systems.
Yes, this wouldn't be a problem and is actually a fairly common practice.
In the recent years I have come to realize that sometimes, however, it is not a good idea to always build your views based on your domain directly. You can take a look at this post:
http://codebetter.com/jpboodhoo/2007/09/27/screen-bound-dto-s/
It is also known as "Presentation Model":
http://martinfowler.com/eaaDev/PresentationModel.html
The idea behind that is basically the following:
Imagine you have the domain entry User, who looks like that :
#Entity
#Data
public class User {
#Id private UUID userId;
private String username;
#OneToMany private List<Permission> permissions;
}
Let's now imagine you have a view where you wanna display that user's name, and you totally don't care about the permissions. If you use your approach of immediately returning the User to the view, Hibernate will make an additional join from the Permissions table because event though the permissions are lazily loaded by default, there is no easy way to signal to the jackson serializer or whatever you are using, that you don't care about them in this particular occasion, so jackson will try to unproxy them (if your transaction is still alive by the time your object is put for json serialization, otherwise you get a nasty exception). Yes, you can add a #JsonIgnore annotation on the permissions field, but then if you need it in some other view, you are screwed.
That a very basic example, but you should get the idea that sometimes your domain model can't be immediately used to be returned to the presentation layer, due to both code maintainability and performance issues.
We were using such approach to simplify design and get rid of many dtos (we were abusing them too much). Basically, it worked for us.
However, in our REST model we were trying to do not expose other relations for an object as you can always create another REST resources to access them.
So we just put #JsonIgnore annotations to relations mappings like #OneToMany or #ManyToOnemaking them transient.
Another problem I see that if you still like to return these relations you would have to use Join.FETCH strategy for them or move transaction management higher so that transaction still exists when a response is serialized to JSON (Open Session In View Pattern).
On my opinion these two solutions are not so good.
You can map the json request without using any library at REST web-services (Jersy)
this sample of code:
This hibernate entity called book:
#Entity
#Table(name = "book", schema = "cashcall")
public class Book implements java.io.Serializable {
private int id;
private Author author; // another hibernate entity
private String bookName;
//setters and getters
}
This web-services function
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public String addBook(Book book) {
String bookName=book.getName();
return bookName;
}
This is sample json request:
{
"bookName" : "Head First Java",
"author" : {
"id" : 1
}
}
Since you are just starting, perhaps you could use Spring Data REST?
This is the project: http://projects.spring.io/spring-data-rest/
And here are some simple examples:
https://github.com/spring-projects/spring-data-book/tree/master/rest
https://github.com/olivergierke/spring-restbucks
As you can see in the examples, there are no extra DTOs beyond the #Entity annotated POJOs.
I have pretty much zero experience with Hibernate, though I've used similar persistence libraries in other languages before. I'm working on a Java project that will require a way to define "models" (in the MVC sense) in text configuration files, generate the database tables automatically, and (ideally) be database-backend-agnostic. As far as I can tell from some quick Googling, Hibernate is the only widely-used backend-agnostic Java database library; while I could write my own compatibility layer between my model system and multiple DB backends, that's a debugging endeavor that I'd like to avoid if possible.
My question is: Can Hibernate be used to store data whose structure is represented in some other way than an annotated Java class file, such as a HashMap with some configuration object that describes its structure? And, if not, are there any other relatively-stable Java database libraries that could provide this functionality?
EDIT: Here's a clearer description of what I'm trying to accomplish:
I am writing a data-modeling library. When a certain method of the library is called, and passed a configuration object (loaded from a text file), it should create a new "model," and create a database table for that model if necessary. The library can be queried for items of this model, which should return HashMaps containing the models' fields. It should also allow HashMaps to be saved to the database, provided their structure matches the configuration files. None of these models should be represented by actual compiled Java classes.
I think you could try use #MapKey annotation provided by JPA (not the Hibernate #MapKey annotation, it's pretty different!).
#javax.persistence.OneToMany(cascade = CascadeType.ALL)
#javax.persistence.MapKey(name = "name")
private Map<String, Configuration> configurationMap = new HashMap<String, Configuration>();
I don't believe Hibernate will let you have a Map as an #Entity but it will let you have a custom class that contains a map field:
#Entity
public class Customer {
#Id #GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
#OneToMany #JoinTable(name="Cust_Order")
#MapKeyColumn(name"orders_number")
public Map<String,Order> getOrders() { return orders; }
public void setOrders(Map<String,Order> orders) { this.orders = orders; }
private Map<String,Order> orders;
}
(example from Hibernate docs)
Additionally, you don't have to use annotations (if that is what you're trying to avoid): Hibernate relationships can be described via xml files and there are utilities (maven plugins for example) which can automatically generate the necessary java pojo's from the xml.
Does your model require a relational database? You might consider a database like Mongo that stores any object you can represent with JSON.
you can configure hibernate to work without any entity classes (beans linked to tables),
1. you need to use xml configuration for this. in place of class use entity-name and in place of <property name="something" use <property node="something".
create a hibernate session with entiy-mode as map.
you can use a map to store and retuive information from db. Remember, since you are using map there will be difficulties in 2-way mapping (this was as of 3.3, not sure if its been fixed in later releses)