I am using spring boot starter 2.1.6 and spring-data-mongo starter version is 2.1.6.RELEASE.
Whenever the server starts i understood spring boot mongo creates the collection schema. For some reason spring boot mongo does not create collection schema for some specific collection. These collections are all the time same ones.
But when i create programatically by myself they are created without error or warning.
mongoTemplate.createCollection("collectionName");
I would like to know how to find out why spring boot is not able to
create these specific collections.
For example below is one of the collection which is not created automatically by spring boot.
#Document(collection = "subscription_histories")
public class SubscriptionHistoryModel extends AbstractModel {
private static final long serialVersionUID = 4424861457985412905L;
#NotNull
#DBRef(lazy = true)
#Field("customer")
private CustomerModel customer;
#NotNull
#Field("subscription_from")
private Instant subscriptionFrom;
#NotNull
#Field("subscription_to")
private Instant subscriptionTo;
public CustomerModel getCustomer() {
return customer;
}
public void setCustomer(CustomerModel customer) {
this.customer = customer;
}
public Instant getSubscriptionFrom() {
return subscriptionFrom;
}
public void setSubscriptionFrom(Instant subscriptionFrom) {
this.subscriptionFrom = subscriptionFrom;
}
public Instant getSubscriptionTo() {
return subscriptionTo;
}
public void setSubscriptionTo(Instant subscriptionTo) {
this.subscriptionTo = subscriptionTo;
}
#Override
public int hashCode() {
return super.hashCode();
}
#Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}
I've been struggling on this issue for past 2 days as well. Finally found why was this happening.
So if you're using docker for the mongodb and mongodb express. Idk for some reason the data is being stored locally and accessed from there and not the mongodb docker container. I've also installed mongodb locally and was trying to run using docker as well.
So, you must check if there are any other places where your mongodb service might be running and your program might be referring to that place!
Related
Environment:
spring-boot v2.0.4 RELEASE
spring-data-aerospike v2.0.1.RELEASE
java - 8
Here are my application code and properties.
// application.properties
aerospike.hosts=xxx:3000
aerospike.namespace=test
// aerospike configuration class
#Configuration
#RequiredArgsConstructor
#EnableConfigurationProperties(AerospikeConfiguration.AerospikeConfigurationProperties.class)
#EnableAerospikeRepositories(basePackageClassses = TestAeroRepository.class)
public class AerospikeConfiguration extends AbstractAerospikeDataConfiguration {
private final AerospikeConfigurationProperties aerospikeConfigurationProperties;
#Override
protected Collection<Host> getHosts() {
return Host.parseServiceHosts(aerospikeConfigurationProperties.getHosts());
}
#Override
protected String nameSpace() {
return aerospikeConfigurationProperties.getNamespace();
}
#Data
#Validate
#ConfigurationProperties("aerospike")
public static class AerospikeConfigurationProperties {
#NotEmpty
String hsots;
#NotEmpty
String namespace;
}
}
# Entity class
#Value
#Document
#Builder(toBuilder = true)
#AllArgsConstructor
public class testEntity() {
#Id
int id;
#Field
String name;
#Field
String timestamp;
}
#Repository
public interface TestAeroRepository extends AerospikeRepository<TestEntity, Integer> {
}
public interface TestAeroService {
void save();
}
#Service
#RequiredArgsConstructor
public class TestAeroServiceImpl implements TestAeroService {
private final TestAeroRepository testAeroRepository;
#Override
public void save(TestEntity entity) {
testAeroRepository.save(entity);
}
}
I checked Aerospike client connection has no problem.
But error is occurred when save() method is executed.
org.springframework.cglib.core.ReflectUtils.defineClass(Ljava/lang/String;[BLjava/lang/ClassLoader;Ljava/security/ProtectionDomain;Ljava/lang/Class;)Ljava/lang/Class;
Have to make sets before execute the application? I didn't make sets.
Any problem with my code?
You’re using an old version of spring-data-aerospike (2.0.1.RELEASE was released on April 2019) is there any chance you can upgrade to the latest version? 2.4.2.RELEASE
You can see how to setup a simple spring data aerospike application here: https://medium.com/aerospike-developer-blog/simple-web-application-using-java-spring-boot-aerospike-database-and-docker-ad13795e0089
Please share the entire project’s code and the entire exception.
I would look into:
The configuration class (The Aerospike Beans creation).
The content of the testEntity class - are you using #Id annotation on the primary key field?
Extending the repository class with specifying the testEntity object (… extends AerospikeRepository<testEntity, Object> {) you can see an example in the link I added.
The set is automatically created and takes the name of your object class, which is testEntity in your case. For example, based on your code, if you do not specify a collection in the #Document annotation a set named "testEntity" will automatically be created. I added the #Document(collection = "testEntitys") annotation and all I did was create two set. Once you insert your first record, run the "SHOW SETS" aql command and it will be there. So that's one way to do it.
I am trying to delete an index from the database that I put before.
#Indexed(unique = true)
private String name;
After I delete the #Indexed(unique = true), I need to remove it from the MongoDB too. And I need to do it within the Spring. Can I do it with #PostConstruct or something?.
Spring-Data's MongoTemplate has a method to give you IndexOperations for a collection which lets you create and drop indices of a collection.
Attention:
According to db.collection.dropIndex() documentation the drop of a index will lock the whole collection until its dropped and all queries using the index are killed.
Here is an example which deletes an index 'name' from the collection 'products' during app start.
#Component
class IndexManager implements InitializingBean {
private MongoTemplate mongoTemplate;
public IndexManager(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
#Override
public void afterPropertiesSet() {
mongoTemplate.indexOps("products").dropIndex("name");
}
}
There are multiple ways to execute code during spring application startup. More ways to do it can be found here: running-setup-logic-on-startup-in-spring
I solve this with using #PostConstruct. While app is initializing I did remove the index with MongoTemplates. The Code is like this:
#PostConstruct
private void removeIndex() {
IndexOperations indexOperations = mongoTemplate.indexOps(YourEntity.class);
Optional<IndexInfo> indexInfo = indexOperations.getIndexInfo().stream().filter(i->i.getName().equals("name")).findFirst();
if(indexInfo.isPresent()) {
indexOperations.dropIndex("name");
}
}
When I send request http://localhost:8080/pets My server response 404!
The code on github: https://github.com/Teemitze/petstore
I build war file. Version spring 2.2.6.RELEASE
#Controller
#RequestMapping("/pets")
public class PetsController {
#Autowired
PetRepository petRepository;
#PostMapping("/addPet")
public void addPet(Pet pet) {
petRepository.save(pet);
}
#GetMapping
#ModelAttribute
public String pets(Model model) {
List<Pet> petList = new ArrayList<>();
petList.add(getPet());
petList.add(getPet());
petList.add(getPet());
model.addAttribute("pets", petList);
return "allPets";
}
public Pet getPet() {
Pet pet = new Pet();
pet.setId(1L);
pet.setName("Мурзик");
pet.setPrice(100);
pet.setBirthday(Date.valueOf("2019-12-12"));
pet.setSex("М");
return pet;
}
}
I checked out your code and found a few issues.
1) Package structure
Move controller, dto, repo packages to the main package (com.petstore)
Since the main application is inside the (com.petstore) package and the controller is outside the package, so it fails to scan the class.
2) Use annotation #Entity for the Pet entity class with #Id for the id property
3) Remove #ModelAttribute from pets() method since you are not binding any method parameter.
After this, I see the /pets
SpringBoot project requires define some configuration conventions that need to be follow in order to start a minimum application.
Some points you have to consider when you want to start a spring boot application.
For example:
Your SpringBootApplication(PetstoreApplication) class should be in the directory level above your other packages so that it can scan all classes.
If you want to use SpringData JPA you have to manage your model class
#Data
#Entity
public class Pet {
#Id
private long id;
private String name;
private String sex;
private Date birthday;
private byte[] photo;
private int price;
}
because it is handled by respository
public interface PetRepository extends CrudRepository<Pet, Long>
Need minimum configuration for Thymeleaf https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html
You are making a GET request for a resource "/pets" so no need #ModelAttribute in get mapping method
#GetMapping()
public String allPets(Model model) {
Make sure your html files is under resources/templates directory.
Check out the reference docs
spring mvc
spring data jpa
I want to have similar functionality as I get with the JPA #PrePersist but in a mongodb database. Reading the spring data mongodb documentation I found the entity callbacks: https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#entity-callbacks. They seem to work for what I need so I'm trying to implement some callbacks. I know there are some alternatives for what I'm doing (auditing annotations) but I want to keep with this for the moment.
This is how I register the callback, my entity definition and the repository:
#Configuration
public class BeforeSaveCallbackConfiguration {
#Bean
BeforeSaveCallback<Measurement> beforeSaveMeasurement() {
return (entity, document, collection) -> {
entity.setTimestamp(System.currentTimeMillis());
System.out.println("Before save, timestamp: " + entity.getTimestamp());
return entity;
};
}
}
public interface MeasurementRepository extends MongoRepository<Measurement, String> {
}
#Document
public class Measurement {
private String id;
private long timestamp;
private Float value1;
private Float value2;
// constructor, getters, setters ...
}
I save the entity using measurementRepository.save method of the repository. I actually see the printed line from the callback with the timestamp. However the data saved in the mongodb collection always have timestamp set to 0. Does anyone have any hint?
You implement BeforeConvertCallback interface can work for you:
#Component
public class TestCallBackImpl implements BeforeConvertCallback<Measurement> {
#Override
public Measurement onBeforeConvert(Measurement entity, String collection) {
entity.setTimestamp(System.currentTimeMillis());
return entity;
}
}
I'm beginner in java programming. And I try to write simple stand alone application with spring data. To basic example which is here http://spring.io/guides/gs/accessing-data-jpa/ I want to add, auditing mechanism which will store previous values for objects. I want in customer entity, on #PreUpdate store old values in another table, but I do not know how.
#Entity
#EntityListeners(AuditingEntityListener.class)
public class Customer implements Serializable {
...
#Transient
private transient Customer savedState;
#PreUpdate
public void onPreUpdate() {
if (!savedState.firstName.equals(this.firstName)) {
log.info(String.format("first name was modified, new value =%s, old value=%s",this.firstName, savedState.firstName ));
}
}
#PostLoad
private void saveState(){
this.savedState = (Customer) SerializationUtils.clone(this); // from apache commons-lang
}