GithubHelp home page GithubHelp logo

kaiso / relmongo Goto Github PK

View Code? Open in Web Editor NEW
52.0 4.0 9.0 562 KB

Java relationship-enabled domain model persistence framework for MongoDB

Home Page: https://kaiso.github.io/relmongo

License: Apache License 2.0

Java 100.00%
mongodb dbref spring-data-mongodb onetomany onetoone relational java mapping bi-directional spring

relmongo's People

Contributors

kaiso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

relmongo's Issues

Can't create relation with `Long` identifier

I'm trying to create relation with Long id. Application throws next exception:

java.lang.ClassCastException: class java.lang.Long cannot be cast to class org.bson.types.ObjectId (java.lang.Long is in module java.base of loader 'bootstrap'; org.bson.types.ObjectId is in unnamed module of loader 'app')
	at org.bson.Document.getObjectId(Document.java:249)
	at io.github.kaiso.relmongo.mongo.DocumentUtils.mapIdentifier(DocumentUtils.java:63)
	at io.github.kaiso.relmongo.mongo.PersistentRelationResolver.resolveOnLoading(PersistentRelationResolver.java:56)
	at io.github.kaiso.relmongo.events.processor.RelMongoProcessor.onAfterLoad(RelMongoProcessor.java:57)
	at org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener.onApplicationEvent(AbstractMongoEventListener.java:56)
	at org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener.onApplicationEvent(AbstractMongoEventListener.java:31)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:400)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:354)
	at org.springframework.data.mongodb.core.ReactiveMongoTemplate.maybeEmitEvent(ReactiveMongoTemplate.java:2009)
	at org.springframework.data.mongodb.core.ReactiveMongoTemplate$ProjectingReadCallback.doWith(ReactiveMongoTemplate.java:2588)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:100)
	at com.mongodb.reactivestreams.client.internal.ObservableToPublisher$1.onNext(ObservableToPublisher.java:68)
	at com.mongodb.async.client.AbstractSubscription.onNext(AbstractSubscription.java:135)
	at com.mongodb.async.client.AbstractSubscription.processResultsQueue(AbstractSubscription.java:203)
	at com.mongodb.async.client.AbstractSubscription.tryProcessResultsQueue(AbstractSubscription.java:159)
	at com.mongodb.async.client.AbstractSubscription.addToQueue(AbstractSubscription.java:117)
	at com.mongodb.async.client.MongoIterableSubscription$2.onResult(MongoIterableSubscription.java:101)
	at com.mongodb.async.client.MongoIterableSubscription$2.onResult(MongoIterableSubscription.java:87)
	at com.mongodb.operation.AsyncQueryBatchCursor.next(AsyncQueryBatchCursor.java:135)
	at com.mongodb.operation.AsyncQueryBatchCursor.next(AsyncQueryBatchCursor.java:99)
	at com.mongodb.async.client.MongoIterableSubscription.requestMoreData(MongoIterableSubscription.java:87)
	at com.mongodb.async.client.MongoIterableSubscription$1.onResult(MongoIterableSubscription.java:55)
	at com.mongodb.async.client.MongoIterableSubscription$1.onResult(MongoIterableSubscription.java:48)
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
	at com.mongodb.async.client.AsyncOperationExecutorImpl$1$1.onResult(AsyncOperationExecutorImpl.java:70)
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
	at com.mongodb.operation.FindOperation$3.onResult(FindOperation.java:822)
	at com.mongodb.operation.OperationHelper$ReferenceCountedReleasingWrappedCallback.onResult(OperationHelper.java:353)
	at com.mongodb.operation.CommandOperationHelper$1.onResult(CommandOperationHelper.java:389)
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
	at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor$2.onResult(DefaultServer.java:207)
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
	at com.mongodb.connection.CommandProtocolImpl$1.onResult(CommandProtocolImpl.java:102)
	at com.mongodb.connection.DefaultConnectionPool$PooledConnection$1.onResult(DefaultConnectionPool.java:458)
	at com.mongodb.connection.UsageTrackingInternalConnection$2.onResult(UsageTrackingInternalConnection.java:110)
	at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
	at com.mongodb.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:381)
	at com.mongodb.connection.InternalStreamConnection$2$1.onResult(InternalStreamConnection.java:359)
	at com.mongodb.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:651)
	at com.mongodb.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:618)
	at com.mongodb.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:487)
	at com.mongodb.connection.InternalStreamConnection$5.completed(InternalStreamConnection.java:484)
	at com.mongodb.connection.netty.NettyStream.readAsync(NettyStream.java:236)
	at com.mongodb.connection.netty.NettyStream.handleReadResponse(NettyStream.java:266)
	at com.mongodb.connection.netty.NettyStream.access$600(NettyStream.java:66)
	at com.mongodb.connection.netty.NettyStream$InboundBufferHandler.channelRead0(NettyStream.java:325)
	at com.mongodb.connection.netty.NettyStream$InboundBufferHandler.channelRead0(NettyStream.java:322)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:628)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:528)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:482)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:834)

java.lang.IllegalArgumentException when @Id field is null but type of @Id field is String

I have a child Document that has an @id field of type String (as opposed to ObjectId). As per the documentation, if the related child document has no id ( does not exist in the database) it needs to be created and automatically linked to the parent document by RelMongo.
When I try to save the child document, I get a java.lang.IllegalArgumentException "Can not set java.lang.String field xxx.Person.id to org.bson.types.ObjectId"

In the checkIdentifier method of class io.github.kaiso.relmongo.events.callback.PersistentPropertyConvertingCallback a check is made to see if the Mongo id is null, and if so, a new ObjectId is generated.

			if (id == null) {
				objectIdReaderCallback.getIdField().set(obj, ObjectId.get());
			}

However, the code above assumes the type of the id field is ObjectId and hence the exception.

Many to one N + 1 queries

By executing a query to retrieve the parent documents that has a many to one relationship to child documents, relmongo will issue 100 queries to retrieve the child documents when the number of returned parent documents are 100. As the number of documents in mongodb increases, the queries being executed separately can easily affect the performance of the application. Is it possible to load all child documents by 1 queries instead of N queries?

Creating a reference inside Subcollection

I'm trying to reference an item inside a subcollection and it's not working. Collection and Subcollection are embedded.

Does this work?

Document
+Collection
+Subcollection
+Reference

Read collection name from @document value in addition to collection attribute.

While debugging #62 I found some issue when not using @Document(collection="cars")
In PersistentPropertySavingCallback Line 115

String collection = ReflectionsUtil.getGenericType(field).getAnnotation(Document.class).collection();

Only a getter for collection() is used. However like in my example you can define the collection name also by omitting document= and just using the value attribute.

@Document("cars")
data class Car(
    @Id
    val id: String,
    val name: String,
)

The logic therefore ignores the collection name. Unfortunately it does not solve the problem I mentioned above

Add multi level relations loading support

I having an issue when I fetching objects that have relationship in more than one level. I have 3 different classes that reference to each other by a one-to-one relationship, as shown below.

@Document(collection = "products")
@TypeAlias(value = "product")
public class Product {
  
  @Id
  private String id;

  private String name;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  @JoinProperty(name = "variations")
  private List<ProductVariation> variations;

}
@Document(collection = "variations")
@TypeAlias(value = "variation")
public class ProductVariation {

  @Id
  private String variationId;

  private String name;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  @JoinProperty(name = "options")
  private List<Option> options;

}
@Document(collection = "options")
@TypeAlias(value = "option")
public class Option {

  @Id
  private String optionId;

  private String text;

}

Through a spring-controller and spring repository I can add some data to MongoDB database. But then my issue starts. As you can see in the repsonse below the option does not have any text value when I use a ProductRepository to fetch the data. I have checked the MongoDB database and the data has been saved correctly.

[
  {
    "id": "5ef4998e0a994e434d6cce86",
    "name": "My Product Name",
    "variations": [
      {
        "id": "5ef4998e0a994e434d6cce84",
        "name": "My Product Variation Name",
        "options": [
          {
            "id": "5ef4998e0a994e434d6cce88",
            "text": null
          }
        ]
      }
    ]
  }
]

However, if I use a ProductVariationRepository and do the fetch one level down, it works perfectly.

[
  {
    "id": "5ef4998e0a994e434d6cce84",
    "name": "My Product Variation Name",
    "options": [
      {
        "id": "5ef4998e0a994e434d6cce88",
        "text": "My options value"
      }
    ]
  }
]

Is this a bug? Can't you have multi level relationship? Or have I missed something in my configuration ?

OneToMany relation is saved as sub documents and not in a separate collection after update to spring boot 2.7.5

Hi,
after upgrading from spring boot 2.5.5 to 2.7.5, relmongo saves the related objects as subdocuments:

class Case{
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.NONE)
    @JoinProperty(name = "persons")
    private List<Person> persons = new ArrayList<>();
}

class Person{
   @Id
    String _id;
   String name;
   String email;
}

Saving the Case, results in this DB entry:

{
    "persons" : [
        {"_id": "XXX", "name"="Paul", "emai"l; "paul@..."},...
    ]
}

Loading does not touch the "persons" collection as well!

This behavior started with the upgrade to ne new Spring boot version.

Failed in bidirectional mapping when one of the audit fields gets updated.

I have manyToOne and oneToMany relationship like

class A {
...
@OneToMany
List<B> b;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
}
class B {
...
@ManyToOne
A a;
}

This fails because the auditing field lastModifiedDate, gets updated (I think) and the save method fails. removing the auditing field works fine.
org.springframework.data.mapping.MappingException: Cannot lookup property @io.github.kaiso.relmongo.annotation.ManyToOne(mappedBy=gists, fetch=LAZY)private com.timecloud.source.entity.pojo.ClassA com.timecloud.gist.entity.ClassB.source on null intermediate! Original path was: source.lastModifiedDate on com.timecloud.gist.entity.ClassB.

suggestion

hi good work,

  1. i suggest to add more attributes for collection mapping (exp : orphanRemoval, mappedBy),

  2. there is a bug problem when use bidirection relationship (exp : person -> cars , car -> own person) when persist data there an exception for rerurcive data (spring boot + jackson) because the 2 side off relationship refrences recursivly one to other (person -> list cars & car -> person -> list cars -> ......, son can resole this without loose the the reference of 2 relationship

Cascade Type REMOVE not deleting child attributes on Query.

I have entities similar to this.

public class Parent {
    @OneToMany(fetch= FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinProperty(name="childrens")
    private List<Child> childrens;

}
public class Child {
   @ManyToOne(mappedBy = "childrens", fetch= FetchType.EAGER)
    private Parent parent;
}

I've implemented something like

public class ParentRepository extends MongoRepository<Parent, ObjectId> {
    @DeleteQuery( value = "{'property1' : ?0, 'property2' : ?1 }")
    void deleteParentByProperties(String property1, String property2);
}

when I do parentRepository.deleteParentByProperties("param1", "param2");
-> It deleted the parent but not the child (Note: this is a custom method implemented with a Query - but still native?)

when I do parentRepository.delete(parent);
-> It deletes the child as well (works as expected). (Note : This is a native method)

Instead of individual parent, I wanted to delete all parent that match a certain condition and avoid doing a fetch query.

JoinTable analogue

Hello again @kaiso!

Could you kindly tell me if it is possible with relmongo:

Example with mysql:
@ManyToMany(fetch=FetchType.EAGER) @JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))

Thank you in advance.
P.S. Sorry for writing here - haven't found your contact details. I will close issue)

How to update and delete child document in oneToMany relationship

How to update and delete child document using parentId and childId in oneToMany relationship

Update: @PutMapping("/posts/{postId}/comments/{commentId}")
public Comment updateComment(@PathVariable (value = "postId") Long postId,@PathVariable (value =
"commentId"),Long commentId,@requestbody Comment commentRequest) {
// Update Logic - query
}

Delete: @DeleteMapping("/posts/{postId}/comments/{commentId}")

Many to one N + 1 queries

By executing a query to retrieve the parent documents that has a many to one relationship to child documents, relmongo will issue 100 queries to retrieve the child documents when the number of returned parent documents are 100. As the number of documents in mongodb increases, the queries being executed separately can easily affect the performance of the application. Is it possible to load all child documents by 1 queries instead of N queries?

RelMongo improvement

hi

i have one issue (A) and one suggestion (B)

A. with last exemple (car & person), when load person document
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.XXX)
@JoinProperty(name = "cars")
List cars;

  1. XXX = EAGER : person loaded with cars and print in console with success
  2. XXX = LAZY : person load (include cars) with success, but when print this person in console, an exception appear like this :
    java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.example.demo.entity.Car

in spring data jpa we can resolve this by add : spring.jpa.hibernate.enable_load_lazy_no_trans=true (application.properties) and all work fine, how about spring data mongodb ???

B. orphanRemoval implemnation in @OneToMany

Not all collections are shown via "show collections"

Hello @kaiso Kaiso!

I faced such problem:
I have two models linked via
@OneToOne (fetch = FetchType.EAGER) @JoinProperty (name = "stats").
Everything works fine, but when I try "show collections" in console or view them in mongodb-compass, I see only one - the first (there should be two collections, as I understand it). Please tell me how to display the second collection.
Thank you in advance.

BRGDS

P.S.
example:
"stats": { "_id": "392395918", "_relmongo_target": "FootballMatchStat" }
So I cant find FootballMatchStat collection anywhere

logo contribution

Hello @kaiso

I wanted to design a new logo for relmongo. I think this looks more modern. I just want to help. I can send you a pr if you want. Also, Please tell me if there is a place you want to customize. I will wait for feedback.

Have a nice day!

mongo2

Support for _id of type Long

According to the mapping chapter of mongodb 1.3.3.RELEASE, the _id field can be of any type other than arrays.

https://docs.spring.io/spring-data/mongodb/docs/1.3.3.RELEASE/reference/html/mapping-chapter.html

_7.1.1 How the '_id' field is handled in the mapping layer
MongoDB requires that you have an '_id' field for all documents. If you don't provide one the driver will assign a ObjectId with a generated value. The "id" field can be of any type the, other than arrays, so long as it is unique.

I've forked 3.4.0-RC1 and adapted io.github.kaiso.relmongo.util.ObjectIdReaderCallback to also support Long.

Do you think that is sensible? I guess other types should be supported as well?

I've also had to adapt the mapIdentifier method in io.github.kaiso.relmongo.mongo.DocumentUtils respectively.

I've create the following pull request: #58

If you are happy with this, I will try to adapt it accept any type other than arrays.

Many thanks and happy weekend!

Delete is not working in case JsonSubTypes

When I create Collection1, all SubCollection are created.
But when I delete Collection1, SubCollection not deleted

@Document
public class Collection1 {
    @Id
    private String id;
    @OneToOne(fetch = EAGER, cascade = ALL)
    @JoinProperty(name = "superCollection")
    private SuperCollection superCollection;
....
}
@JsonTypeInfo(use = NAME, include = PROPERTY, property = "type", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = SubCollection1.class, name = "subCollection1"),
        @JsonSubTypes.Type(value = SubCollection2.class, name = "subCollection2")
})
@Document
public class SuperCollection {
    @Id
    private String id;
....
}
public class SubCollection1 extends SuperCollection {
    private Integer value;
...
}

Order of List<> changes when using @OneToMany relation

Hi,

we are using a one to many relation from a PersistedCase to a PersistedPerson:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.NONE) @JoinProperty(name = "offers") private List<PersistedOffer> offers = new ArrayList<>();

Then we add Persons in a specific order and save it. In 20-50% of the cases the order of the Persons lists order has changed when I look into the DB.

Best
Andreas

Bug when using multiple relationships to same collection in one class

I found another thing that I think is a bug. In our model we would like to have a one-to-many relationship to another collection but in two different fields. But that seems to screw things up.

In the example below I have two fields on the Offer class, products and addons, referring with a OneToMany relationship to the same collection products. The products for both fields has been saved earlier and exists in the database.

@Document(collection = "offers")
@TypeAlias(value = "offer")
public class Offer {

  @Id
  private String id;

  private String name;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.NONE)
  @JoinProperty(name = "products")
  private List<Product> products;

  @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.NONE)
  @JoinProperty(name = "products")
  private List<Product> addons;

}
@Document(collection = "products")
@TypeAlias(value = "product")
public class Product {
  
  @Id
  private String id;

  private String name;

} 

Below is the data added. I have a ModelMapper converter that converts the string ids in products and addons to real objects before saving. And it works when I remove the relationship to addons.

{
  "name": "My Offer",
  "category": "CATEGORY_X",
  "subcategory": "SUB_CATEGORY_Y",
  "products": [
    "5ef5f73d9959571a685ade51"
  ],
  "addons": [
    "5ef5f75d9959571a685ade54"
  ],
  "rules": []
}

The result in MongoDB is a document that looks like this. It has saved the product reference from addon into the products field. And addon reference is completely missing.

{
    "_id" : ObjectId("5ef5f7ba9959571a685ade56"),
    "name" : "My Offer",
    "category" : "CATEGORY_X",
    "subcategory" : "SUB_CATEGORY_Y",
    "_class" : "offer",
    "products" : [ 
        {
            "_id" : ObjectId("5ef5f75d9959571a685ade54"),
            "_relmongo_target" : "products"
        }
    ]
}

Thanks for any help you could provide. It's a great library.

relmongo improvement

hi

its work (i forgot to instantiate list cars in person document) however after persistence data , in mongodb car document have no info about owner (no reference for person in car document)

sans titre

E11000 duplicate key error collection

Hi,
First thanks for the wonderfull plugin.

I have two classes Agency and Country with OneToOne relation


@Document
public class Agency {
	
	@Id
	@JsonIgnore
	@Getter
	private String id;
	
	@Getter @Setter
	@Indexed(unique = true)
	private String agencyCode;
	
	//The login of the agency
	@Getter @Setter
	private String login;
	
	//The password of the agency
	@Getter @Setter
	private String password;
	
	@JsonIgnore
	@OneToOne(fetch=FetchType.EAGER)
    @JoinProperty(name = "country")
	@Getter @Setter
    private  Country country;
    
//    @OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.PERSIST)
//    @JoinProperty(name="mobilemoney")
//    private List<MobileMoneyOperator> mobileMoneyService;
    

	/**
	 * constructor with required parameters
	 * @param agencyCode
	 * @param login
	 * @param password
	 * @param country
	 */
	public Agency(String agencyCode, String login, String password, Country country) {
		super();
		this.agencyCode = agencyCode;
		this.login = login;
		this.password = password;
		this.country = country;
	}    
}
public class Country  {

	@Id
	@JsonIgnore
	private String id;
	
	@Indexed(unique = true)
	private	String countryCode;
	
	//The name of the country
	@Indexed(unique = true)
	private String name;
	
	@OneToOne(mappedBy = "country", fetch = FetchType.EAGER)
    private Agency agency;

}

My use case :

  • I Created many countries first, then I created each Agency by giving to each agency the country code.

Problem:
When I create a country with an agency to null, the first time it is good. The 2nd time, I got the error

Caused by: com.mongodb.MongoWriteException: E11000 duplicate key error collection: gara-cash-transaction.country index: agency.agencyCode dup key: { agency.agencyCode: null }
	at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1055) ~[mongodb-driver-3.11.1.jar:na]
	at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:498) ~[mongodb-driver-3.11.1.jar:na]
	at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:482) ~[mongodb-driver-3.11.1.jar:na]
	at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:476) ~[mongodb-driver-3.11.1.jar:na]

This is probably do to the fact that I added in country

@OneToOne(mappedBy = "country", fetch = FetchType.EAGER)
    private Agency agency;

How is it possible to create all countries first with Agency to null, then to add for each country an agency ?

null is detected as key, in agency.agencyCode, but I don't want him to create cascade.
E11000 duplicate key error collection: gara-cash-transaction.country index: agency.agencyCode dup key: { agency.agencyCode: null }

Thanks in advance.

No bean named 'mongoTemplate' available

I have a problem with some tests

I use

@RunWith(SpringRunner.class)
@WebMvcTest(UtilisateursRest.class)
@AutoConfigureMockMvc(addFilters = false)
class UsersRestTest {

The error :

Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
	at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTemplate$RelMongo$OK$RLMIndexCreator': Cannot resolve reference to bean 'mongoTemplate' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
....
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available

For other tests, its work fine :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = MOCK)
@TestMethodOrder(OrderAnnotation.class)
@AutoConfigureMockMvc
class UserRestIT {

and

@ExtendWith(MockitoExtension.class)
class UserServiceTest {

Exception encountered upon retrieval of relmongo annotated entity from repository

When creating some "app" entities, and assigning a few to a user entity,

<app1 = new Application(...), app2=new Application(...), app3 =... omitted for brevity>

    User user1 = User.builder()
        .uuid("uuid1")
        .name("Don Johnson")
        .app(app1)
        .app(app3)
        .build();

    appRepo.save(app1);
    appRepo.save(app2);
    appRepo.save(app3);
    userRepo.save(user1);

My user entity:

@Data
@Document
@Builder
public class User {
  @Id 
  private String uuid;
  private String name;
  @OneToMany(fetch=FetchType.EAGER)
  @JoinProperty(name="apps")
  @Singular
  private Set<Application> apps;
}

My app entity:

@Data
@Document
@Builder
public class Application {
  @Id
  //@NotBlank
  //@Length(max =250)
  private String uuid;
  //@NotBlank
  @Length(max=50)
  private String name;
  private String version;
  private Date updatedAt;

Without the @EnableRelationalMongo annotation, I see the apps are persisted as expected, using spring data rest I see my 3 apps at the /apps endpoint, and at the /users endpoint, I see user 1 has apps "app1" and "app3" associated with it.

When I enable this framework by adding the @EnableRelationalMongo annotation, the following exception is encountered upon hitting the /users endpoint. (It seems that the afterLoad() logic is querying for the related entities, but the _ids of the user's associated apps generated by the framework do not match the _ids of the apps actually persisted by spring.

java.lang.IllegalArgumentException: Collection must not be null or empty!
	at org.springframework.util.Assert.hasText(Assert.java:276) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
	at io.github.kaiso.relmongo.mongo.DatabaseLoader.getDocumentsById(DatabaseLoader.java:28) ~[relmongo-2.0.0-RC1.jar:na]
	at io.github.kaiso.relmongo.mongo.PersistentRelationResolver.resolveOnLoading(PersistentRelationResolver.java:54) ~[relmongo-2.0.0-RC1.jar:na]
	at io.github.kaiso.relmongo.events.listener.MongoEventListener.onAfterLoad(MongoEventListener.java:46) ~[relmongo-2.0.0-RC1.jar:na]
	at org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener.onApplicationEvent(AbstractMongoEventListener.java:56) ~[spring-data-mongodb-2.0.5.RELEASE.jar:2.0.5.RELEASE]
	at org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener.onApplicationEvent(AbstractMongoEventListener.java:31) ~[spring-data-mongodb-2.0.5.RELEASE.jar:2.0.5.RELEASE]

I'm using spring boot 2.0.2 managed dependencies and

<dependency>
      <groupId>io.github.kaiso.relmongo</groupId>
      <artifactId>relmongo</artifactId>
      <version>2.0.0-RC1</version>
    </dependency>

[BUG] (From Example): Field 'cars' second contructor parameter for 'name' is always null?

Using:

    id("org.springframework.boot") version "2.3.4.RELEASE"
    id("io.spring.dependency-management") version "1.0.10.RELEASE"

    implementation("io.github.kaiso.relmongo:relmongo:3.4.0")
    implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
    implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")

Having the following class setup:

@Document("persons")
data class Person(
    @Id
    val id: String,
    val name: String,
    @OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST)
    @JoinProperty(name = "cars")
    val cars: List<Car>
)

@Document("cars")
data class Car(
    @Id
    val id: String,
    val name: String,
)

@Repository
interface PersonRepository : MongoRepository<Person, String>

And using it as followed in a unit test:

    @Test
    fun `experiment`() {
        val car = Car("001", "BWM")
        val person = Person("101", "Peter", listOf(car))
        personRepository.save(person)
        val foundPerson = personRepository.findAll()[0]
        assertThat(foundPerson.cars[0].name).isEqualTo("101")
    }

The result is always an exception:

Failed to instantiate com.alemannigame.backend.persistence.mongodb.document.Car using constructor fun <init>(kotlin.String, kotlin.String): com.alemannigame.backend.persistence.mongodb.document.Car with arguments 001,null
org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.alemannigame.backend.persistence.mongodb.document.Car using constructor fun <init>(kotlin.String, kotlin.String): com.alemannigame.backend.persistence.mongodb.document.Car with arguments 001,null
	at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:240)
	at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:87)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:344)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:317)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readCollectionOrArray(MappingMongoConverter.java:1119)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1578)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1478)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1527)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1490)
	at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:71)
	at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:49)
	at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:262)
	at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:235)
	at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:87)

Enable multiple mongoTemplate support

  • Change the @EnableRelMongo annotation to have a new attribute mongoTemplateRef.
  • Change the RelMongo logic to be able to target a specifig mongoTemplate.

Exception - unable to set mappedBy child object

I am using below structure

class ProfileEntity{
.......
@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.PERSIST)
@JoinProperty(name="emailNotificationsId")
private List emailNotifications;
}

public class EmailNotificationsEntity {

@Id
private Integer emailNotificationsId;
@Field(name="email_notifications_name")
private String name;

@ManyToOne(mappedBy = "emailNotifications")
private List<ProfileEntity> profiles;

}

For this structure i am getting below error while fetching ProfileEntity data

io.github.kaiso.relmongo.exception.RelMongoProcessingException: unable to set mappedBy child object Can not set java.util.List field com.test.core.profile.entity.EmailNotificationsEntity.profiles to com.test.core.profile.entity.ProfileEntity

missing mappedBy and null childs with OneToMany association

I'll take the example you have posted in the wiki: (Person and Cars)

class Person{
...
@OneToMany(fetch= FetchType.LAZY, cascade = CascadeType.ALL)
@JoinProperty(name="cars")
private List<Car> cars = new ArrayList<>();

public addCar(Car c){
car.setPerson(this);
this.getCars().add(car);
}
}
class Cars{
...
@ManyToOne(mappedBy = "cars", fetch= FetchType.EAGER)
private Person owner;
}
Person p = new Person();
Car c = new Car();
p.addCar(car)
p.save();

//saving the 2nd car overrides the 1st car values
Car car2 = new Car();
p.add(car2);
p.save();

I've seen instances where saving car2 creates null (default values) of the class. Am I doing something wrong?

Apparently, when this.getCars() is called it loads the first car with the correct id but all of the other properties are empty/class defaults (and not the saved value).

MappingException when removing based on query using lt

I was working on relmongo v3.0.0. Recently, I realized that there were newer versions avaialble, so I decided to upgrade to v3.2.0. However, one of the test cases that was passing previously started to fail on me.

Code

Criteria expression = Criteria.where("expirationDate").lt(LocalDateTime.now());
Query query = new Query().addCriteria(expression);
return mongoTemplate.remove(query, UserPasswordReset.class).wasAcknowledged();

The above code was/is working with v3.0.0., but not with versions greater than v3.0.0. (v3.0.1, v3.1.0 and v3.2.0).

[Note :: I played around with other mongoTemplate methods like find and it seems to work with all versions. Also, I have similar codes using query and criterion that is based on String and remove method, and those are working without any issues on all versions.]

The associated class

@Getter
@ToString
@Document(collection = "passwordResets")
@EntityListeners(AuditingEntityListener.class)
public class UserPasswordReset {

    @Id
    private ObjectId id;

    @NotNull
    private String email;

    private String token = UUID.randomUUID().toString();

    private LocalDateTime expirationDate = LocalDateTime.now();

    @CreatedDate
    private LocalDateTime createdDate;

    // overloaded constructor
    public UserPasswordReset(String email){ this.email = email; }
}

Error message

org.springframework.data.mapping.MappingException: Expected to read Document Document{{$lt=Mon Mar 16 14:30:08 CDT 2020}} into type class java.time.LocalDateTime but didn't find a PersistentEntity for the latter!

	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:244)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1493)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1391)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:380)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:297)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:277)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:247)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:196)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:192)
	at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:80)
	at io.github.kaiso.relmongo.events.callback.PersistentPropertyCascadingRemoveCallback.<init>(PersistentPropertyCascadingRemoveCallback.java:50)
	at io.github.kaiso.relmongo.events.processor.RelMongoProcessor.onBeforeDelete(RelMongoProcessor.java:110)
	at org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener.onApplicationEvent(AbstractMongoEventListener.java:68)
	at org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener.onApplicationEvent(AbstractMongoEventListener.java:31)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:402)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:359)
	at org.springframework.data.mongodb.core.MongoTemplate.maybeEmitEvent(MongoTemplate.java:2276)
	at org.springframework.data.mongodb.core.MongoTemplate$9.doInCollection(MongoTemplate.java:1694)
	at org.springframework.data.mongodb.core.MongoTemplate$9.doInCollection(MongoTemplate.java:1689)
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:545)
	at org.springframework.data.mongodb.core.MongoTemplate.doRemove(MongoTemplate.java:1689)
	at org.springframework.data.mongodb.core.MongoTemplate.remove(MongoTemplate.java:1677)
	at org.springframework.data.mongodb.core.MongoTemplate.remove(MongoTemplate.java:1670)
	at com.timecloud.user.repository.UserPasswordResetCustomRepositoryImpl.deleteAllInactive(UserPasswordResetCustomRepositoryImpl.java:45)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	

Issue when persisting using oneToMany annotation in relmongo

While performing a sample test of relmongo in my project I am facing the given issue:

java.lang.RuntimeException: java.lang.NoSuchMethodError: com.krakken.learningmongo.models.Person$$EnhancerByCGLIB$$af5ebd31: method 'void <init>()' not found

	at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:281)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.mongodb.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:158)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220)
	at jdk.proxy2/jdk.proxy2.$Proxy114.findById(Unknown Source)
	at com.krakken.learningmongo.repository.PersonRepositoryTests.testOneToManyMappingBetweenCarAndPerson(PersonRepositoryTests.java:71)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.NoSuchMethodError: com.krakken.learningmongo.models.Person$$EnhancerByCGLIB$$af5ebd31: method 'void <init>()' not found
	at com.krakken.learningmongo.models.Person$$EnhancerByCGLIB$$af5ebd31.newInstance(<generated>)
	at io.github.kaiso.relmongo.mongo.PersistentRelationResolver.lazyLoader(PersistentRelationResolver.java:55)
	at io.github.kaiso.relmongo.events.callback.PersistentPropertyPostLoadingCallback.doWith(PersistentPropertyPostLoadingCallback.java:103)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:728)
	at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:707)
	at io.github.kaiso.relmongo.events.processor.RelMongoProcessor.onAfterConvert(RelMongoProcessor.java:127)
	at io.github.kaiso.relmongo.events.processor.RelMongoProcessor.onApplicationEvent(RelMongoProcessor.java:86)
	at io.github.kaiso.relmongo.config.RelMongoBeanPostProcessor$RelMongoEventPublisher.publishEvent(RelMongoBeanPostProcessor.java:84)
	at org.springframework.data.mongodb.core.EntityLifecycleEventDelegate.publishEvent(EntityLifecycleEventDelegate.java:53)
	at org.springframework.data.mongodb.core.MongoTemplate.maybeEmitEvent(MongoTemplate.java:2363)
	at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3284)
	at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:2874)
	at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java:2536)
	at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:817)
	at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findById(SimpleMongoRepository.java:127)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277)
	... 21 more

Here are my models

Car.java

package com.krakken.learningmongo.models;

import io.github.kaiso.relmongo.annotation.ManyToOne;
import lombok.Builder;
import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "car")
@Data
public class Car {

    @Id
    private String id;

    @Indexed(unique = true)
    private int identifier;

    public Car(int identifier) {
        this.identifier = identifier;
    }

    private String manufacturer;
    private Color color;

    @ManyToOne(mappedBy = "cars")
    private Person Owner;
}

Person.java

package com.krakken.learningmongo.models;

import io.github.kaiso.relmongo.annotation.CascadeType;
import io.github.kaiso.relmongo.annotation.FetchType;
import io.github.kaiso.relmongo.annotation.JoinProperty;
import io.github.kaiso.relmongo.annotation.OneToMany;
import lombok.*;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.Document;


import java.util.List;


@Document(collection = "person")
@Data
@Builder
public class Person {

    private ObjectId id;
    private String name;
    private String email;


    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinProperty(name = "carsrefs")
    @Singular
    private List<Car> cars;
}

and I have added the relMongo annotation like this,

package com.krakken.learningmongo;

import io.github.kaiso.relmongo.config.EnableRelMongo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@SpringBootApplication
@EnableRelMongo(mongoTemplateRef = "mongoTemplate")
@EnableMongoAuditing
public class LearningMongoApplication {

    public static void main(String[] args) {
        SpringApplication.run(LearningMongoApplication.class, args);
    }

}

While performing the given series of test, I am facing the above issue.

package com.krakken.learningmongo.repository;


import com.krakken.learningmongo.config.MongoSpringConfiguration;
import com.krakken.learningmongo.models.Account;
import com.krakken.learningmongo.models.Car;
import com.krakken.learningmongo.models.Color;
import com.krakken.learningmongo.models.Person;
import com.mongodb.MongoConfigurationException;
import io.github.kaiso.relmongo.util.RelMongoConstants;
import org.bson.Document;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;


import java.util.Arrays;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;


@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class PersonRepositoryTests {

    @Autowired
    private PersonRepository personRepository;

    @Autowired
    private CarRepository carRepository;

    @Autowired
    private MongoOperations mongoOperations;

    @BeforeEach
    void clearDatabase() {
        personRepository.deleteAll();
        carRepository.deleteAll();
    }

    @Test
    @DisplayName("Test one to many mapping between car and persons")
    void testOneToManyMappingBetweenCarAndPerson() {
        Car car1 = new Car(1);
        car1.setColor(Color.BLUE);
        car1.setManufacturer("BMW");
        Car car2 = new Car(2);
        car2.setColor(Color.RED);
        car2.setManufacturer("BMW");

        car1 = carRepository.save(car1);
        car2 = carRepository.save(car2);

        Person person = Person.builder()
                .name("Dave")
                .email("[email protected]")
                .cars(Arrays.asList(new Car[]{car1, car2}))
                .build();
        person = personRepository.save(person);

        Optional<Car> foundCarOptional = carRepository.findById(car1.getId());
        assertTrue(foundCarOptional.isPresent());

        Car foundCar = foundCarOptional.get();

        assertNotNull(foundCar.getOwner());
        assertEquals(foundCar.getOwner().getId(), person.getId());

        Optional<Person> foundPersonOptional = personRepository.findById(person.getId().toString());
        assertTrue(foundPersonOptional.isPresent());

        Person foundPerson = foundPersonOptional.get();

        assertEquals(2, foundPerson.getCars().size());

    }
}

Can you tell me which changes I have to make in order to make it work?

I am in ubuntu 23.04.

PersistentPropertyPostLoadingCallback.close() never called.... memory leak?

Hi Kaiso!

I'm getting OutOfMemory errors in my application and after analysing the heap dump, it looks like it may be due to the close() method of PersistentPropertyPostLoadingCallback never being called.

I do have to mention though, that I am running on a fork... which has a feature which you decided not to include (#60). So maybe it will only ever be me having this problem, as I instantiate an instance of PersistentPropertyPostLoadingCallback within PersistentPropertyPostLoadingCallback itself.

Thought I would mention it just in case though.

Many thanks again for your great work, keep it up!

RelMongo not working with AbstractConfiguration (MongoDB 4.0 Transactions)

Hi All,

Issue:
For enabling transactions on MongoDB 4.0 it is required to use AbstractConfiguration. When I add this configuration RelMongo stops working.

Implementation:

public class MongoTransactionConfig extends AbstractMongoConfiguration {

@Bean
MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
    return new MongoTransactionManager(dbFactory);
}

@Value("${spring.data.mongodb.host}")
private String host;

@Value("${spring.data.mongodb.port}")
private Integer port;

@Value("${spring.data.mongodb.database}")
private String database;


@Override
protected String getDatabaseName() {
    return database;
}

@Override
@Bean
public MongoClient mongoClient() {
return new MongoClient(host, port);
}

}

PS: Great dependency, I love how it smooth it is.

Thanks,
Rafael

Support for annotations within nested objects

I have a scenario where an object has an embedded object (field) which itself is persisted as part of the outer @document but annotated fields within the embedded object should be scanned for @OnetoOne and @OneToMany annotations.

Example:

ArticleDTO {

  @Id
  private Long id;

  @OneToOne(...)
  @JoinProperty(...)
  private OtherDTO other;

  private MetaDTO meta;

}

MetaDTO {

  @Id
  private Long id;

  @OneToOne(...)
  @JoinProperty(...)
  private FooDTO foo;

}

Currently, the annotations on the FooDTO field in MetaDTO would never be read.

How about a @nested annotation, which would then perform the same functionality on the MetaDTO field?

Exception encountered when saving relmongo annotated entity via Spring Data Repository

    <dependency>
      <groupId>io.github.kaiso.relmongo</groupId>
      <artifactId>relmongo</artifactId>
      <version>1.0.0-RC2</version>
    </dependency>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency> //Using Spring Boot 2.0.2 dependency management 
public interface UserRepository  extends CrudRepository<User,String> {

}
public interface ApplicationRepository extends CrudRepository<Application,String> {
}
@Data
@Document
@Builder
public class User {
  @Id @NotBlank
  private String id;
  private String name;
  @OneToMany(fetch=FetchType.EAGER)
  @Singular
  private Set<Application> apps;
}
@Data
@Document
@Builder
public class Application {
  @Id
  //@NotBlank
  @Length(max =250)
  private String uuid;
  //@NotBlank
  @Length(max=50)
  private String name;
  private String version;
  private Date updatedAt;
  //@NotBlank
   @Length(max=500)
  private String summary;
  @URL
  //@NotBlank
  private String icon;
  private String description;
  @Valid
  @Singular
  private List<AccessUrl> urls;

  @Valid
  private Support support;
}
  @Autowired
  private ApplicationRepository appRepo;

  @Autowired
  private UserRepository userRepo;

...

    appRepo.save(app1);
    appRepo.save(app2);
    appRepo.save(app3);
    userRepo.save(user1);
java.lang.NoSuchMethodError: org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent.getDBObject()Lcom/mongodb/DBObject;
	at ****io.github.kaiso.relmongo**.events.listener.MongoEventListener.onBeforeSave**(MongoEventListener.java:53) ~[relmongo-1.0.0-RC2.jar:na]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.