I am having trouble getting mapstruct and immutables to work.
#Value.Immutable
public abstract class FoobarValue {
public abstract Integer foo();
}
#Value.Immutable
public abstract class TargetFoo {
public abstract Integer foo();
}
#Mapper
public interface ImmutableMapper {
ImmutableMapper INSTANCE = Mappers.getMapper(ImmutableMapper.class);
public TargetFoo toTarget(FoobarValue foobarValue);
}
Main class to test
public class FoobarValueMain {
public static void main(String... args) {
FoobarValue value = ImmutableFoobarValue.builder()
.foo(2)
.build();
ImmutableMapper mapper = ImmutableMapper.INSTANCE;
System.out.println(mapper.toTarget(value).foo());
}
}
The error that I get is
Exception in thread "main" java.lang.IllegalStateException: Cannot build TargetFoo, some of required attributes are not set [foo]
at org.play.ImmutableTargetFoo$Builder.build(ImmutableTargetFoo.java:158)
at org.play.ImmutableMapperImpl.toTarget(ImmutableMapperImpl.java:21)
at org.play.FoobarValueMain.main(FoobarValueMain.java:12)
My build.gradle is as follows
ext {
mapstructVersion = "1.4.0.Beta2"
immutablesVersion = "2.8.2"
}
dependencies {
annotationProcessor "org.immutables:value:$immutablesVersion" // <--- this is important
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.0.Beta2"
compileOnly "org.immutables:value:$immutablesVersion"
implementation "org.mapstruct:mapstruct:${mapstructVersion}"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
As per reference this should all work out of the box. What am I missing here ?
The reason why it doesn't work is because you are not using the JavaBean convention.
You need to prefix your methods with get
e.g.
#Value.Immutable
public abstract class TargetFoo {
public abstract Integer getFoo();
}
Related
I am using Java unit tests. When we give the parameters correctly, the unit test should work without any errors (green). But I am getting such an error. Java version 1.8
Expecting code to raise a throwable.
TicTacToeService
public class TicTacToeService {
public void play(int x, int y) {
if(x<0)
throw new IllegalArgumentException("x cannot be negative");
if (y < 0)
throw new IllegalArgumentException("y cannot be negative");
if (x > 2)
throw new IllegalArgumentException("x cannot be greater than 2");
if (y > 2)
throw new IllegalArgumentException("y cannot be greater than 2");
}
}
TicTacToeTest
public class TicTacToeTest {
private TicTacToeService ticTacToeService = new TicTacToeService();
#Test
public void givenXIsNegativeExpectException(){
int x = -1;
int y = 1;
Assertions.assertThatThrownBy(() -> ticTacToeService.play(x, y))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("X cannot be negative");
}
#Test
public void givenYIsNegativeExpectException(){
int x = 1;
int y = -1;
Assertions.assertThatThrownBy(() -> ticTacToeService.play(x, y))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("y cannot be negative");
}
}
dependencies
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation("org.modelmapper:modelmapper:2.3.7")
implementation 'org.springframework.boot:spring-boot-starter-validation'
testCompile group: 'junit', name: 'junit', version: '4.4'
implementation 'org.liquibase:liquibase-core'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testCompile group: 'org.assertj', name: 'assertj-core', version: '3.6.1'
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0'
}
What is the problem? please help me
I suspect that you are using assertThatThrownBy but in reality, you want to use assertThrows. You can check this link for example.
I can declare my own custom runtime exception write it as below
service class
#Service
public class TicTacToeService {
public void play(int x, int y) {
if (x < 0)
throw new XNegativeException("x cannot be negative");
if (y < 0)
throw new YNegativeException("y cannot be negative");
if (x > 2)
throw new XLimitException("x cannot be greater than 2");
if (y > 2)
throw new YLimitException("y cannot be greater than 2");
}
static class XNegativeException extends RuntimeException{
public XNegativeException(String message) {
super(message);
}
}
static class YNegativeException extends RuntimeException{
public YNegativeException(String message) {
super(message);
}
}
static class XLimitException extends RuntimeException{
public XLimitException(String message) {
super(message);
}
}
static class YLimitException extends RuntimeException{
public YLimitException(String message) {
super(message);
}
}
}
Test File
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class TicTacToeServiceTest {
private final TicTacToeService ticTacToeService = new TicTacToeService();
#Test
void testXIsNegative() {
Assertions.assertThrows(TicTacToeService.XNegativeException.class,
() -> ticTacToeService.play(-1, 0));
}
#Test
void testYIsNegative() {
Assertions.assertThrows(TicTacToeService.YNegativeException.class,
() -> ticTacToeService.play(0, -898));
}
#Test
void testXLimitReached() {
Assertions.assertThrows(TicTacToeService.XLimitException.class,
() -> ticTacToeService.play(3, 0));
}
#Test
void testYLimitReached() {
Assertions.assertThrows(TicTacToeService.YLimitException.class,
() -> ticTacToeService.play(0, 3));
}
}
I'm attempting to create basic Axon/Spring application by tutorial, but faced with strange error like: NoHandlerForCommandException: No handler was subscribed to command. It seems that Axon can't see #CommandHandler annotation.
Here my files:
aggregate
#Aggregate
#NoArgsConstructor
public class Account {
#AggregateIdentifier
private UUID accountId;
private Double balance;
#CommandHandler
public Account(CreateAccountCommand command) {
apply(new AccountCreatedEvent(command.getAccountId(), command.getName()));
}
#EventSourcingHandler
protected void on(AccountCreatedEvent event) {
this.accountId = event.getAccountId();
this.balance = 0.0;
}
}
event
#AllArgsConstructor
#Getter
public class AccountCreatedEvent {
private UUID accountId;
private String name;
}
command
#Getter
public class CreateAccountCommand {
#TargetAggregateIdentifier
private UUID accountId;
private String name;
public CreateAccountCommand(UUID accountId, String name) {
this.accountId = accountId;
this.name = name;
}
}
spring boot conf
#SpringBootApplication
public class App {
#Configuration
public static class TestConfiguration {
#Bean
public EventStorageEngine inMemoryEventStorageEngine() {
return new InMemoryEventStorageEngine();
}
}
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
this is how i send cmd
#Component
public class AppLoader {
#Autowired
private CommandGateway cmdGateway;
#PostConstruct
public void init() {
cmdGateway.send(new CreateAccountCommand(UUID.randomUUID(), "test"));
}
}
my build.gradle
buildscript {
ext {
springBootVersion = '2.0.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'io.yourpoint.nettnews'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'org.axonframework', name: 'axon-test', version: '3.3.5'
compile group: 'org.axonframework', name: 'axon-spring-boot-starter', version: '3.3.5'
compile('org.springframework.boot:spring-boot-starter-webflux')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('io.projectreactor:reactor-test')
}
It is very likely that performing the CommandGateway#send() call in a #PostConstruct is to early for Axon..
As it currently stands, all the command, event and query handlers typically get registered after all your beans have been initialized.
Moving the CommandGateway#send() behind a REST endpoint should give you a big enough time frame to ensure all the handlers have been registered.
So in short, it's a timing issues why you get the NoHandlerForCommandException.
We (at AxonIQ) see benefit in sending some sort of application events as soon as all the handlers have been registered. That's a thing for the future though.
Hope this helps you out #Benjamin!
I am in the process of developing a Spring Boot application and came across this error when starting the server. I am not sure if I am incorrectly defining any annotations or missing any dependencies. Any help would be appreciated.
Main class:
#SpringBootApplication
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class DemoApplication {
public static void main(String[] args) {
System.out.println("Hello world");
SpringApplication.run(DemoApplication.class, args);
}
}
UserService class:
#Service
public class UserService implements IUserService {
#Autowired
private UserDAO userDAO;
#Override
public List<UserDTO> getAllUsers() {
List<User> entities = userDAO.getUsers();
List<UserDTO> users = new ArrayList<UserDTO>();//Will never use directly User Object, will be using Tranferable objects
Iterator<User> iterator = entities.iterator();
while(iterator.hasNext()) {
User user = iterator.next();
users.add(ApiDTOBuilder.userToUserDTO(user));//We are building UserDTO object.
}
return users;
}
#Override
public UserDTO getUserByUsername(String username) {
User user = userDAO.getUser(username);
return ApiDTOBuilder.userToUserDTO(user);
}
#Override
public void createUser(UserDTO user) {
userDAO.createUser(ApiDTOBuilder.userDTOToUser(user));
}
#Override
public void updateUser(UserDTO user) {
userDAO.updateUser(ApiDTOBuilder.userDTOToUser(user));
}
#Override
public void deleteUser(String username) {
userDAO.deleteUser(username);
}
}
UserDAO class:
#Repository
public class UserDAO implements IUserDAO {
#PersistenceContext
EntityManager em;//JPA EntityManager is used to access a database in a particular application. It is used to manage persistent entity instances, to find entities by their primary key identity(As here is Username), and to query over all entities.
#Override
#Transactional
public User getUser(String username) {
return em.find(User.class, username); //Here entitymanager can find the username as it has the capability to find an entity by unique identifies
}
#Override
#Transactional
public List<User> getUsers() {
List<User> resultList = em.createQuery("FROM user_tbl", User.class).getResultList();
return resultList;
}
#Override
#Transactional
public void createUser(User user) {
em.persist(user);//Make an instance managed and persistent.
}
#Override
#Transactional
public void updateUser(User user) {
em.merge(user);//Merge the state of the given entity into the current persistence context.
}
#Override
#Transactional
public void deleteUser(String username) {
User user = this.getUser(username);
em.remove(user);//Remove the entity instance.
}
}
Build.gradle:
buildscript {
ext {
springBootVersion = '2.0.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final')
compile('javax.xml.bind:jaxb-api:2.2.11')
compile('org.springframework.boot:spring-boot-starter-test:2.0.2.RELEASE')
compile('com.sun.xml.bind:jaxb-core:2.2.11')
compile('com.sun.xml.bind:jaxb-impl:2.2.11')
runtime('org.springframework.boot:spring-boot-devtools')
runtime('mysql:mysql-connector-java')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Error message:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userDAO in com.example.demo.service.UserService required a bean of type 'javax.persistence.EntityManagerFactory' that could not be found.
Action:
Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.
I saw all the relevant answers and tried to implement those suggestions like adding dependencies, adding notations in the main class, etc. But it shows the same error. Please someone help me out. Thank you in advance.
P.S: Github link of my application: https://github.com/heliOpenxCell/demo
i got the same your problem, just add this to your maven or gradle, it work for me!
Maven:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>9.0.10</version>
</dependency>
Gradle:
compile group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '9.0.10'
I'm working on AOP for the first time. It's not working - Maybe I'm mixing up Spring AOP and AspectJ, I'm not sure.
dependency declaration in Gradle file
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
...
compile("org.aspectj:aspectjweaver:1.8.9")
}
}
Configuration class
#Configuration
#EnableAspectJAutoProxy
public class AspectJConfiguration{
#Bean
public MailQueueServiceAspect mailQueueServiceAspect(){
return new MailQueueServiceAspect();
}
}
Aspect Class
#Aspect
public class MailQueueServiceAspect {
private final Logger log = LoggerFactory.getLogger(MailQueueServiceAspect.class);
#Pointcut("execution(* com.biscom.bsend.core.SaveMailHelper.aopTest())")
private void mailUpdatePointCut(){}
#After("mailUpdatePointCut()")
public void afterSampleCreation(JoinPoint joinPoint) {
log.info("Mail Queue updated successfully.");
}
}
Joint-Point holder class
public class SaveMailHelper extends AbstractHelper<SaveMailInput, SaveMailOutput> {
#Inject
private MailQueueService mailQueueService;
private final Logger log = LoggerFactory.getLogger(SaveMailHelper.class);
#Override
protected void executeHelper(SaveMailInput input, SaveMailOutput output) throws AbstractException {
MailQueue mailQueue = mailQueueService.get(input.getId(), new MailQueue());
BlockExecutor e = new BlockExecutor();
e.execute(input.getMailFrom().shouldSet(mailQueue.isNew(), mailQueue.getMailFrom()), () ->{
mailQueue.setMailFrom(input.getMailFrom().get());
});
output.setEntity(mailQueue);
aopTest();
}
public void aopTest(){
log.info("AOPTest method called.");
}
}
I also tried avoiding Configuration class by placing #Component annotation over Aspect class.
I'm using the latest version of Spring and I'm getting startup errors when I attempt to inject the same generic type twice and the generic type's implementation uses caching.
Below is the simplest example I can create to duplicate the error.
// build.gradle dependencies
dependencies {
compile 'org.springframework.boot:spring-boot-starter'
compile 'org.springframework.boot:spring-boot-starter-web'
}
// MyApplication.java
#SpringBootApplication
#EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
#Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}
// HomeController.java
#RestController
#RequestMapping(value = "/home")
public class HomeController {
#Autowired
public HomeController(
GenericService<String> s1,
GenericService<String> s2, // <-- Notice GenericService<String> twice
GenericService<Integer> s3
) {}
}
// GenericService.java
public interface GenericService<T> {
public T aMethod();
}
// IntegerService.java
#Service
public class IntegerService implements GenericService<Integer> {
#Override
#Cacheable("IntegerMethod")
public Integer aMethod() {
return null;
}
}
// StringService.java
#Service
public class StringService implements GenericService<String> {
#Override
#Cacheable("StringMethod")
public String aMethod() {
return null;
}
}
This compiles fine, but when I run the application, I get the following error:
No qualifying bean of type [demo.GenericService] is defined: expected single matching bean but found 2: integerService,stringService
I have not tried using qualifiers yet, but I'm guessing that would be a work-around. I will try it after posting this. Ideally, I'd like the autowiring of generics and caching to integrate out-of-box. Am I doing something wrong, or is there anything I can do to get it working?
Thank you!
If you would like to not have to use the #Qualifier in the constructor and still use the interfaces, you could just add a value to the service declarations.
#Service(value = "integerService")
public class IntegerService implements GenericService<Integer> {
#Override
#Cacheable("IntegerMethod")
public Integer aMethod() {
return 42;
}
}
#Service(value = "stringService")
public class StringService implements GenericService<String> {
#Override
#Cacheable("StringMethod")
public Integer aMethod() {
return 42;
}
}
Just to be sure, I created a project with Spring-Boot, compiled and ran it. So the above should work. It's basically the same as what you're already doing, but with less typing.
My previous answer (before modifying) was to do something like this:
// HomeController.java
#RestController
#RequestMapping(value = "/home")
public class HomeController {
#Autowired
public HomeController(
StringService s1,
StringService s2,
IntegerService s3
) {}
}
But you would have to not implement the interfaces to make this work.