SpringBoot GraphQL field name mismatch - spring-boot

It seems that the names defined in the .graphqls file MUST match the field names in the POJO. Is there a way to maybe annotate the field so that they don't have to?
For example, I have something like this in the graphqls file
type Person {
personId: ID!
name: String!
}
Then in my Entity POJO I have like
#Id
#Column(name="PERSON_ID")
#JsonProperty("person_id")
private int personId;
#Column(name="NAME")
#JsonProperty("name")
private String name;
So, the intention is for the field name to be personId and the database to store it as a column called PERSON_ID and for it to get serialized as JSON and GraphQL as person_id
But graphql talks in the language of the schema. So it serializes it as personId which matches the schema field but is not the intention. I could change the schema to be person_id but then I need to change the field too... This isn't the end of the world but it's quite "un-javalike" to have fields named that way.
I am using this library:
compile group: 'com.graphql-java', name: 'graphql-spring-boot-starter', version: '5.0.2'
I have also seen the #GraphQLName annotation in the annotations library but I must be missing something because it doesn't do what I am expecting or maybe I am using it wrong.
Is there some way to get around this or should I just change the names?

GraphQL Java uses PropertyDataFetcher by default to resolve field values (see data fetching section in the docs). This data fetcher works out-of-the box when the data object returned by a top level field data fetcher contains child fields that match the data object property names.
However, you can define your own data fetcher for any field and use whatever rule you need.
So, if you want a schema that looks like this
type Person {
person_id: ID!
name: String!
}
and your entity like this:
class Person {
private int personId;
private String name;
// getters and setters
}
You can write a simple custom data fetcher for the field personId
private RuntimeWiring buildWiring() {
return RuntimeWiring.newRuntimeWiring()
// query root data fetchers wiring
.type(newTypeWiring("Person")
.dataFetcher("person_id", environment -> {
Person person = environment.getSource();
return person.getPersonId();
})
)
// maybe other wirings
.build();
}

Related

FindById doesn't work with UUID in Mongodb SpringData

I try to use Mongodb with Spring Data.
I wanted to use UUID instead of ObjectId. I have followed this tutorial: https://www.baeldung.com/java-mongodb-uuid (some differences might exist because I use Kotlin). I took path 2 where I added Entity callback. When I create a new entity it is saved to the database with UUID as I wanted. If I use mongo console I can type:
db.home.find({_id: UUID("18aafcf9-0c5a-46f3-84ff-1c25b00dd1ab")})
And I will find my entity by id.
However, when I try to do it by code it doesn't work as it should. It will always throw here DataOperationException(NOT_FOUND) because findById returns null.
fun findHomeById(id: String): Home {
val home = homeRepository.findById(id)
return home.unwrap() ?: throw DataOperationException(NOT_FOUND)
}
Here is repository
#Repository
interface HomeRepository: MongoRepository<Home, String>
Abstraction with id.
abstract class UuidIdentifiedEntity {
#Id
var id: UUID? = null // I tried use UUID type and String with the same result
}
And my home class
class Home(
var address: String,
var rooms: Int,
): UuidIdentifiedEntity()
Not sure if this will help, but see if changing your #Id annotation to #MongoId fixes this. Under certain circumstances, Mongo needs to know more about a field being used for an id. #MongoId should give you more control on how the field is stored too.
What is use of #MongoId in Spring Data MongoDB over #Id?

Spring Data JDBC One-To-Many with Custom Column Name

I'm using spring-boot-starter-data-jdbc 2.4.2. In my domain aggregate I need to map a List of Strings that is populated from a column in another table. It is a legacy database so I have no control over the table and column names and need to use custom names. I see there is an #MappedCollection annotation, but can't see how to use it in this scenario. Below is my class:
#Data
#Table("NMT_MOVIE_THEATRE")
public class MovieTheatre {
#Id
#Column("MOVIE_THEATRE_ID")
private Long id;
#Column("ZIP_CODE")
private String zipCode;
// this comes from table NMT_CURRENT_MOVIE, column CM_ID, joined by MOVIE_THEATRE_ID
private List<String> currentMovieIds;
}
Using Spring Data JDBC, how can I create the one-to-many relation?
Wrap your String in a little entity.
#Table("NMT_CURRENTMOVIE")
class MovieId {
#Id
#Column("CM_ID")
final String id
// add constructor, equals and hashCode here or generate using Lombok
}
Then use it in the MovieTheatre. Since you don't have a column for an index, the proper collection to use is a Set
// ...
class MovieTheatre {
// ...
#MappedCollection(idColumn="MOVIE_THEATRE_ID")
Set<MovieId> currentMovieIds;
}
Note that equals and hashCode is important as well as the constructor taking all arguments used in those, since the entity is used in a Set.

how to insert a object in mongodb using spring

required format image
I want to object data into MongoDB using spring and I have hardcoded it.
please how to write a schema for that and I have taken it as an example only.
I have a different type of categories in it I have taken only clothes.
please tell me how to write one schema for a different type of categories and query too.
please find the attachment for your reference
I would recommend going though Spring Data MongoDB documentation for specifics on mapping java objects to MongoDB documents. Your case would look similar to:
#Document
public class Clothes {
#Id
private ObjectId id;
private Men men;
private Women women;
// getters & setters
}
You would need to define each sub class but this should be the gist of it.
What you can do is create a simple POJO (Plain Old Java Object) and with that you can insert that object into the data base. The the following example:
#Document
public class OAuthModel implements Serializable {
#Id
String username;
#Indexed
String oAuthID;
#Indexed
String type;
// Getter and Setters and Construct.
}
When I insert this object in the DB by calling:
OAuthModel authModel = new OAuthModel(username,firebaseToken.getUid(), OAuthHosts.GOOGLE.getType());
oAuthRepo.insert(authModel);
It will then be seen as this in the Database:
Keep in mind this will work no matter what your object looks like, you can have hashmaps etc. The should be a built in serialization.

Spring- How to remove a property from a list of Objects?

I have an Entity "Person" which has following properties,
Id
Name
F-Name
Age
Address
When I call a repository function findAll() on Person, it returns a list of Persons.
List<Person> list = somefuntionToConvertIterableToList(personRepository.findAll());
this list has multiple objects of Person Type.
Person ...... Id1,Name1, F-Name1, Age1, Address1
Person .......IdN,NameN, F-NameN, AgeN, AddressN
I need to remove "Id" from all Persons, what should I do?
I know we can use "remove" to delete an element of list, but how to delete a property with in an element?
I think you need used : #JsonIgnore in Id look like:
#JsonIgnore
Field you want remove in reponse.
Or you can create DTO and put all field you want return look like :
public class PersonDTO {
//all field you want return
}
You can of course set id null or add ignores in serialization but maybe you do not want to load id at all. Usually you then would use DTO or Tuple to decide what fields to populate. So not first to populate all and then remove unneeded (I have not used your Person but just one simplified example class).
Tuple query in your repository would simply be like (JPQL):
#Query("SELECT te.name AS name, te.created as created FROM TestEntity te")
List<Tuple> findAllTuple();
This would need then do extra work to have tuple to correspond original entity when serialized. So preferably with a DTO, like:
// This class would be exactly as your Person but without that id
#AllArgsConstructor // you need the constructor for new in jpql
public class TestEntityDto {
private String name;
private LocalDateTime created;
}
while the query in your repository would be like:
#Query("SELECT NEW org.example.data.entity.dto.TestEntityDto(te.name, te.created) FROM TestEntity te")
List<TestEntityDto> findAllDto();

Nested objects data modeling for cassandra

I am using spring data cassandra and having trouble understanding how the data model should be. I understand that cassandra tables are generally denormalized so that means if I have a customer object that looks like this
{
name: "Test Customer",
address: {
city: "New york",
state: "NY"
}
}
The corresponding POJOs would like this
#Table
public class Customer {
#PrimaryKey //just using this as key for this example
private String name;
private Address address;
}
public class Address {
private String city;
private String state;
}
So I want to store only the customer objects but have some way to retrieve the address object associated with the customer object. What are some of the common strategies to handle this.
Should I be using the composite/compound key in some way or create a separate POJO where I can store attributes from both objects in a denormlized form or some other way. Any hints would be appreciated.
In Cassandra tables are created on the query which you want to perform (Query driven model).
So please share the query or set of queries which you want to perform on table.

Resources