Open xLegna opened 4 years ago
it interests me too. This code is working, but not too nice.
Hi @Vmarci94,
To use my contentStore like this:
@Autowired private FileContentStore contentsRepo;
Yes that is how you can autowire the content store into another part of your code in order to make use of it.
This is my interface, should I add @repository to the interface?
No, that is a Spring Data construct. Spring Content does not require this.
Who should create the bean FileContentStore?
Spring Content will create it for you. When your application starts Spring Content will see the FileContentStore and it will see spring-content-fs on your classpath and inject a proxy.
This code is working, but not too nice.
Not too nice because the IDE has underlined it?
Thank You the quick answer.
Sorry the "not too nice" expression. Rather a little confusing to my reviewers. They are very trusting in Intellij IDEA ...
Although You said, the @reposirtoy annotation is a Spring Data construct, and Spring Content does not required this, I added the @Component annotation and solved this little thing.
I would have another question. Although I don't think you'll be happy for him. So I want to set file names, because the directory is a remote drive and several others process use this files. I think this api not entirely for that.
I found DefaultFilesystemStoreImpl class and EnableFilesystemContentRepositories.storeFactoryBeanClass method, i thought write a customFilesystemStoreImpl, but i see the EnableFilesystemContentRepositories annotation is Deprecated. I would be interested in another solution. Do you think I can solve this?
Although You said, the @reposirtoy annotation is a Spring Data construct, and Spring Content does not required this, I added the @component annotation and solved this little thing.
Ah I see what you are saying. This is an IDE thing then. Intellij, in this case, needs to know it is a bean otherwise it will flag it as an error. Although, in our case, spring content stores are bean and will be wired correctly. Just intellij doesn't know that. I will work on this. It would be fine to add a bean annotation on Store so developers don't have annotate their store interfaces directly.
I would have another question. Although I don't think you'll be happy for him. So I want to set file names, because the directory is a remote drive and several others process use this files. I think this api not entirely for that.
Each Store Module (except JPA) has a placement service that is responsible for locating the content in the backing store. This placement service can be configured through a standard Spring converter. It can be done in a couple of ways depending on requirements. Sounds like you know what you want to call the file so I would suggest something like this.
Assume you have a Document entity like this:
@Entity
@Data
public class Document {
@Id
@GeneratedValue(strategy=AUTO)
private Long id;
@ContentId
private UUID contentId;
@ContentLength
private Long contentLength;
@MimeType
private String mimeType;
private String contentPath;
}
Then you can add a configurer like this:
@Configuration
public static class StoreConfig {
@Bean
public FilesystemStoreConfigurer configurer() {
return new FilesystemStoreConfigurer() {
@Override
public void configureFilesystemStoreConverters(ConverterRegistry registry) {
registry.addConverter(new Converter<Document, String>() {
@Override
public String convert(Document document) {
return document.getContentPath();
}
});
}
};
}
}
Now, when you set content for an instance of Document, the placement service will call the converter to establish where to store that contnet.
So, if you created a Document and set its contentPath to /some/path/my-file
. Then your content will be stored in your backing store (remote share) at /some/path/my-file
.
Would this solve your problem?
I updated the docs for the filesystem module to (hopefully) explain this better: https://paulcwarren.github.io/spring-content/refs/snapshot/1.0.x/fs-index.html#_accessing_content
I looked into the problem marker that you highlighted. I also see this BTW. And it is annoying. But I suspect that there are smarts in the spring plugins that make this work for Spring Data repositories.
We would need to add a similar plugin for Spring Content.
@paulcwarren, I only just saw this but there are no plugin changes required my friend. Simply add the internal.org.springframework.content
package to the @ComponentScan
and it should 'just work' E.g.
@SpringBootApplication
@ComponentScan(basePackages = "internal.org.springframework.content")
public class Application {
}
The issue with just using the plain @SpringBootApplication
is that it will only include beans defined within the 'default' package (the package in which the Application
class) is defined and it's sub-packages, as well as the Spring beans. Anything outside of these things has to be added to the @ComponentScan
as a package using basePackages
or as a class using basePackageClasses
to be picked up.
FYI @xLegna, @Vmarci94
Thanks for the info.
Yeah, I think what is weird for me about this is that you don't need this @ComponentScan
application for the correct functioning of the application. intellij's error is in reality a false negative.
Eclipse for example, doesn't exhibit this behavior so (I'm assuming) the eclipse spring plugins generally solve this (on behalf of the developer) and intellij solves it for known spring projects but not others like this one.
We can definitely add this @ComponentScan
to our spring boot starters as that will have no effect for eclipse developers but fix it for intellij developers. But this seems like a bug with the intellij spring problem markers to me.
Hey Paul, interesting point re eclipse, it must be scanning the entire runtime classpath for bean candidates. I know that the IntelliJ plugin generally doesn't do this and relies on configuration to determine where it resolves beans - I'm guessing this is for performance reasons.
I'm not sure adding @ComponentScan
to the SB starters is going to resolve this issue as scanning for the project would still only be done for anything org.spring....
and anything under the default package. Would be good if it did work but my gut says it needs to be added to each project.
@paulcwarren I want to store java.sql.Blob with Spring Data. How to configure you dependency in this case and which exactly dependency do I have to use?
@maksym-matlo the basic setup is described in the jpa guide here. And you might find the set of jpa integration tests a useful guide also. And lastly it should be pretty simple to adapt any of the getting started guides like the rest one. You would just need to swap out fs storage, for jpa storage.
@paulcwarren, I only just saw this but there are no plugin changes required my friend. Simply add the
internal.org.springframework.content
package to the@ComponentScan
and it should 'just work' E.g.@SpringBootApplication @ComponentScan(basePackages = "internal.org.springframework.content") public class Application { }
The issue with just using the plain
@SpringBootApplication
is that it will only include beans defined within the 'default' package (the package in which theApplication
class) is defined and it's sub-packages, as well as the Spring beans. Anything outside of these things has to be added to the@ComponentScan
as a package usingbasePackages
or as a class usingbasePackageClasses
to be picked up.
I tried this but I got Could not find class [internal.org.springframework.content.jpa.config.JpaStoreFactoryBean]
I have a question to use ContentStore.
To use my contentStore like this: @Autowired private FileContentStore contentsRepo;
This is my interface, should I add @Repository to the interface? Who should create the bean FileContentStore?