InvalidDataAccessApiUsageException:Parameter value did not match expected type - spring-data-jpa

please can you help me with the following exception: org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [myCalendar] did not match expected type [pl.sda.jira.calendar.domain.model.Name (n/a)].
I'm having difficulty fixing this error. Grateful if you could let me know what options I have.
The test where I get the error:
#Test
public void shouldGetCalendarEqualToName() throws Exception {
MockHttpServletResponse response = restClient.perform(
MockMvcRequestBuilders.post("/calendars")
.param("columnName", "name")
.param("type", "equals")
.param("value", "myCalendar"))
.andReturn().getResponse();
assertEquals(HttpStatus.OK.value(), response.getStatus());
assertEquals("[{\"name\":\"calendar0\",\"owner\":\"Jon\"}]", response.getContentAsString());
}
My QueryService (pasting only the applicable case from the switch-case):
private Specification<Calendar> createSpecificationsFrom(QueryCriteriaDto queryCriteriaDto) {
switch (queryCriteriaDto.getType()) {
case "equals":
return ((root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.equal(root.get(queryCriteriaDto.getColumnName()), (queryCriteriaDto.getValue())));
}
throw new IllegalArgumentException();
}
My class Name:
public class Name {
private String value;
public Name(String value) {
this.value = value;
}
public String value() {
return value;
}}
I'm also using a Converter:
#Converter
public class NameConverter implements AttributeConverter<Name, String> {
#Override
public String convertToDatabaseColumn(Name name) {
return name.value();
}
#Override
public Name convertToEntityAttribute(String value) {
return new Name(value);
}}

Related

"Object reference not set to an instance of an object." exception while migration with Entity Framework Core 6 by OwnsMany with EntityTypeBuilder

I get a NullReferenceException while migrating my model with EF Core 6.
Here is the error message:
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionBatchExtensions.Run(IConventionBatch batch, InternalForeignKeyBuilder relationshipBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalForeignKeyBuilder.ReuniquifyImplicitProperties(Boolean force)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ForeignKeyPropertyDiscoveryConvention.DiscoverProperties(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext context)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ForeignKeyPropertyDiscoveryConvention.ProcessForeignKeyRequirednessChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext`1 context)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnForeignKeyRequirednessChanged(IConventionForeignKeyBuilder relationshipBuilder)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnForeignKeyRequirednessChangedNode.Run(ConventionDispatcher dispatcher)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.DelayedConventionScope.Run(ConventionDispatcher dispatcher)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ConventionBatch.Run()
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ConventionBatch.Run(IConventionForeignKey foreignKey)
at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.OwnsManyBuilder[TRelatedEntity](TypeIdentity ownedType, MemberIdentity navigation)
at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.OwnsMany[TRelatedEntity](String navigationName, Action`1 buildAction)
at Analyzing.Modules.Project.Persistence.Records.RecordConfiguration.Configure(EntityTypeBuilder`1 builder) in C:\Repo\...\Analyzing.Modules.Project.Persistence\Records\RecordConfiguration.cs:line 27
This is my Configuration class:
public class RecordConfiguration : IEntityTypeConfiguration<Record>
{
public void Configure(EntityTypeBuilder<Record> builder)
{
builder.ToTable("Recordings");
builder.HasKey(x => x.Id);
builder.Property(x => x.Id)
.HasConversion(v => v.Value,
v => new RecordId(v));
builder.Property(x => x.Name);
builder.Property(x => x.Task);
builder.OwnsMany<SensorId>("Sensors", z => {
z.ToTable("Sensors");
z.WithOwner().HasForeignKey("Id");
z.Property(_ => _.Value);
});
}
}
And my SensorId class
public class SensorId : TypedIdValueBase
{
public SensorId(string value) : base(value)
{
}
}
public abstract class TypedIdValueBase : IEquatable<TypedIdValueBase>
{
public string Value { get; }
protected TypedIdValueBase(string value)
{
if (string.IsNullOrEmpty(value))
{
throw new InvalidOperationException("Id value cannot be empty!");
}
Value = value;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is TypedIdValueBase other && Equals(other);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public bool Equals(TypedIdValueBase other)
{
return this.Value.ToLower() == other?.Value.ToLower();
}
public static bool operator ==(TypedIdValueBase obj1, TypedIdValueBase obj2)
{
if (object.Equals(obj1, null))
{
if (object.Equals(obj2, null))
{
return true;
}
return false;
}
return obj1.Equals(obj2);
}
public static bool operator !=(TypedIdValueBase x, TypedIdValueBase y)
{
return !(x == y);
}
}
My model class:
public class Record : AuditableEntity, IAggregateRoot
{
private readonly List<SensorId> _sensors = new();
private Record() { }
private Record(string id, string name, string task)
{
Id = new RecordId(id);
Name = name;
Task = task;
}
public static Result<Record> Create(string id, string name, string task)
{
if (string.IsNullOrEmpty(id))
throw new ArgumentNullException(nameof(id));
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException(nameof(name));
var record = new Record(id, name, task);
return Result.Ok(record);
}
public string Name { get; }
public RecordId Id { get; }
public string Task { get; }
public IReadOnlyList<SensorId> Sensors => _sensors;
public void AddSensorId(SensorId sensorId)
{
_sensors.Add(sensorId);
}
}
It is Entity Framework Core 6 with the SQLite provider. The DbContext is creating while runtime with DesignTimeDbContextFactory.
If I ignore the property Sensors, the migrations finishes successfully.
I don't know where the error comes from. Do you have any idea?
A solution form a another post proposes to delete the snapshot file. This did not solve the problem.
A successful migration including the property Sensors would be nice.

How to map enum to String using Mapstruct

I can find answers where we have String to Enum mapping but I can't find how can I map an Enum to a String.
public class Result {
Value enumValue;
}
public enum Value {
TEST,
NO TEST
}
public class Person {
String value;
}
How can I map this ?
I tried :
#Mapping(target = "value", source = "enumValue", qualifiedByName = "mapValue")
#Named("mapValue")
default Person mapValue(final Value en) {
return Person.builder().value(en.name()).build();
}
mapstruct should support this out of the box.
So #Mapping(target = "value", source = "enumValue") should suffice.
Complete example including target/source classes:
#Mapper
public interface EnumMapper {
#Mapping( target = "value", source = "enumValue" )
Person map(Result source);
}
class Result {
private Value enumValue;
public Value getEnumValue() {
return enumValue;
}
public void setEnumValue(Value enumValue) {
this.enumValue = enumValue;
}
}
enum Value {
TEST, NO_TEST
}
class Person {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
This results in the following generated code:
#Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2022-02-20T12:33:00+0100",
comments = "version: 1.5.0.Beta2, compiler: Eclipse JDT (IDE) 1.4.50.v20210914-1429, environment: Java 17.0.1 (Azul Systems, Inc.)"
)
public class EnumMapperImpl implements EnumMapper {
#Override
public Person map(Result source) {
if ( source == null ) {
return null;
}
Person person = new Person();
if ( source.getEnumValue() != null ) {
person.setValue( source.getEnumValue().name() );
}
return person;
}
}

How to get the currentresource of MultiResourrceItemReader using java config

Below is the code I tried.
#Bean
public MultiResourceItemReader<Map<String, String>> multiResourceItemReader() throws FileNotFoundException {
MultiResourceItemReader<Map<String, String>> resourceItemReader = new MultiResourceItemReader<Map<String, String>>();
inputResources=getMultipleResourceItemreader();
resourceItemReader.setResources(inputResources);
resourceItemReader.setDelegate(reader());
return resourceItemReader;
}
You can use ResourceAware interface to get the resource name.Your Iteam should implement ResourceAware interface.
class Foo implements ResourceAware {
String value;
Resource resource;
Foo(String value) {
this.value = value;
}
#Override
public void setResource(Resource resource) {
this.resource = resource;
}
}
}

JPA Eclipselink JOIN FETCH LAZY relation returning null

I am always getting NULL from a JOIN FETCH clause in my JPA Query, even though I have everything configured as expected:
#XmlRootElement
#XmlAccessorType(XmlAccessType.PROPERTY)
#Entity
#Table(name = "TB_BANNER_IMAGE")
public class BannerImage extends BaseEntity<Integer> {
protected FileReference fileReference;
private String type;
private String labelTitle;
protected BannerImage() {}
#Id
#TableGenerator(name="genBannerImage", table="TB_ID_GENERATOR",
pkColumnName="ID_NAME", valueColumnName="ID_VAL",
pkColumnValue="TB_BANNER_IMAGE", allocationSize=1)
#GeneratedValue(strategy=GenerationType.TABLE, generator="genBannerImage")
#Column(name = "ID_BANNER_IMAGE", unique = true, nullable = false)
public Integer getId() {
return super.getId();
}
#Override
public void setId(Integer id) {
super.setId(id);
}
#Column(name="TYPE")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#OneToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
#JoinColumn(name="ID_FILE_REFERENCE", nullable=false)
public FileReference getFileReference() {
return fileReference;
}
public void setFileReference(FileReference fileReference) {
this.fileReference = fileReference;
}
#Column(name="LABEL_TITLE")
public String getLabelTitle() {
return labelTitle;
}
public void setLabelTitle(String labelTitle) {
this.labelTitle = labelTitle;
}
}
for File Reference Class:
#Entity
#Table(name = "TB_FILE_REFERENCE")
public class FileReference extends BaseNamedEntity<String> {
private String type;
public FileReference() {}
#Id
#TableGenerator(name="genFileReference", table="TB_ID_GENERATOR",
pkColumnName="ID_NAME", valueColumnName="ID_VAL",
pkColumnValue="TB_FILE_REFERENCE", allocationSize=1)
#GeneratedValue(strategy=GenerationType.TABLE, generator="genFileReference")
#Column(name = "ID_FILE_REFERENCE", unique = true, nullable = false)
public String getId() {
return super.getId();
}
#Override
public void setId(String id) {
super.setId(id);
}
#Column(name = "TYPE")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Service class:
#Path("/banner")
public class BannerImageService extends BaseServiceFacade<BannerImage, Integer> {
#SuppressWarnings("unchecked")
#Override
public Crud<BannerImage, Integer> lookupService() throws ServiceLocatorException {
return ServiceLocator.getInstance()
.getLocalHome(ServicesConstants.BANNER_IMAGE_SERVICE);
}
#Override
protected String getDefaultGetQuery() {
return BannerImageDAO.GET_BY_ID_FETCH_FILE_REF;
}
#Override
protected String getDefaultQuery() {
return BannerImageDAO.GET_ALL_FETCH_FILE_REF;
}
}
get REST method of BaseServiceFacade:
#Override
#GET
#Consumes(MediaType.APPLICATION_JSON)
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Path("/{id}")
public T get(#PathParam("id") ID id) {
try {
if (!validateID(id)) {
logMessage("Invalid Entity ID: " + id);
return null;
}
String defaultGetQuery = getDefaultGetQuery();
if (defaultGetQuery != null) {
Map<String, Object> mapParams = new HashMap<String, Object>();
mapParams.put("id", id);
List<T> entityList = getService().search(defaultGetQuery, mapParams);
if (entityList != null && entityList.size() == 1) {
T ent = entityList.get(0);
return ent;
} else {
logMessage("Invalid search by Entity ID: " + id);
}
} else {
return getService().findById(clazz, id);
}
} catch (ServiceException e) {
serviceException(e);
} catch (Exception ex) {
logException(ex);
}
return null;
}
And finally the Service Bean EJB which reads from entityManager:
public class BaseServiceBean<T extends IEntity<ID>, ID extends Serializable> implements Crud<T,ID> {
// ... generic methods to be reused by subclasses
#Override
public List<T> search(String queryOrNamedQuery) throws ServiceException {
return search(queryOrNamedQuery, null, 0, 0);
}
#SuppressWarnings("unchecked")
public List<T> search(String namedQueryOrHql, Map<String, Object> parameters, int start, int chunkSize) {
try {
Query query = createQuery(namedQueryOrHql, getQueryType(namedQueryOrHql));
if (start > 0) {
query.setFirstResult(start);
}
if (chunkSize > 0) {
query.setMaxResults(chunkSize);
}
addParameters(query, parameters);
List<T> result = query.getResultList();
afterSearch(result);
return result;
} catch (NoResultException nre) {
nre.printStackTrace();
} catch (ClassCastException cce) {
cce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void afterSearch(List<T> result) {
}
// etc...
implementation specific class for BannerImageService:
#Stateless(mappedName="ejb/BannerImageService")
public class BannerImageServiceBean extends BaseServiceBean<BannerImage, Integer> implements BannerImageServiceBeanRemote, BannerImageServiceBeanLocal {
#Override
protected void afterSearch(List<BannerImage> result) {
if (result != null && result.size() == 1) {
BannerImage bannerImage = result.get(0);
bannerImage.getFileReference();
}
super.afterSearch(result);
}
// additional code ...
When I try to fetch my BannerImage class together with it's corresponding FileReference member I always get NULL even though in my DB there is an existing foreign key present:
JPQL:
"SELECT a FROM BannerImage a join fetch a.fileReference WHERE a.id = :id";
Generated SQL:
SELECT t1.ID_BANNER_IMAGE, t1.LABEL_TEXT, t1.LABEL_TITLE, t1.TYPE,
t1.ID_FILE_REFERENCE, t0.ID_FILE_REFERENCE, t0.NAME,
t0.TYPE FROM TB_FILE_REFERENCE t0, TB_BANNER_IMAGE
t1 WHERE (t0.ID_FILE_REFERENCE = t1.ID_FILE_REFERENCE) AND t1.ID_BANNER_IMAGE = 1
in my DB the record shows a correct reference:
BANNER_IMAGE:
1;"";"main";"2bdbb063d0d0ee2939c89763945d9d9e";"banner1.png";"image/png"
If I execute :
select * from TB_FILE_REFERENCE where ID_FILE_REFERENCE = '2bdbb063d0d0ee2939c89763945d9d9e'
I can find the record in the DB, although my EclipseLink JPA Implementation always returns null:
EclipseLink Version 2.5.2-M1
This is how the Entity gets passed from Service Layer to the
Can someone help pointing why the JOIN FETCH is not properly working?
I faced a similar issue and looking closely I see that this issue was happening only to entities recently created/saved. Then I figured that it has something to do with eclipselink cache. I solved this problem by adding this line before making a join fetch JPQL query,
em.getEntityManagerFactory().getCache().evictAll();
em.createQuery("SELECT a FROM BannerImage a join fetch a.fileReference WHERE a.id = :id").getResultList();
HTH!

JsonProvider for Jersey 2.5 in Glassfish 4 does not mapping properties

I am using jersey as rest client, but I have problems when application is actually deployed as war on Glassfish 4. When I run it from test it works okay, but in deployed application mapping to POJO return all properties as null.
I tried MoxyJsonProvider, JacksonJsonProvider also custom GsonProvider, but result is same.
Client constructor:
public DockerClientImpl(String restApiUrl) {
restURL = restApiUrl;
restClient = ClientBuilder
.newBuilder()
.register(GsonProvider.class)
.build();
}
One of get methods:
#Override
public List<Container> getContainers(boolean all, boolean latest, int limit, boolean showSize, String since, String before) throws DockerException {
Response response = restClient
.target(restURL)
.path(CONTAINERS_LIST)
.queryParam("all", all)
.queryParam("limit", limit)
.queryParam("since", since)
.queryParam("before", before)
.queryParam("size", showSize)
.request(MediaType.APPLICATION_JSON)
.get();
switch (response.getStatus()) {
case 200:
LOGGER.info("Container list succesfully retrieved");
break;
case 400:
LOGGER.error("Bad request parameter");
throw new DockerException("Bad request parameter");
case 500:
LOGGER.error("Docker Server Error");
throw new DockerException("Docker Server Error");
default:
throw new DockerException("Unknown Error");
}
Type type = new TypeToken<Collection<Container>>() {
}.getType();
List<Container> result = response.readEntity(new GenericType<List<Container>>() { });
LOGGER.debug(String.format("Response: %s", result));
return result;
}
Container POJO:
#SerializedName("Id")
private String id;
#SerializedName("Command")
private String command;
#SerializedName("Image")
private String image;
#SerializedName("Created")
private long created;
#SerializedName("Status")
private String status;
#SerializedName("Ports")
private Port[] ports; //Example value "49164->6900, 49165->7100"
#SerializedName("SizeRw")
private int size;
#SerializedName("SizeRootFs")
private int sizeRootFs;
#SerializedName("Names")
private String[] names;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Port[] getPorts() {
return ports;
}
public void setPorts(Port[] ports) {
this.ports = ports;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getSizeRootFs() {
return sizeRootFs;
}
public void setSizeRootFs(int sizeRootFs) {
this.sizeRootFs = sizeRootFs;
}
public String[] getNames() {
return names;
}
public void setNames(String[] names) {
this.names = names;
}
And currently used Gson Provider:
#Provider
#Consumes({MediaType.APPLICATION_JSON, "text/json"})
#Produces({MediaType.APPLICATION_JSON, "text/json"})
public class GsonProvider implements MessageBodyWriter<Object>,
MessageBodyReader<Object> {
private static final String UTF_8 = "UTF-8";
private Gson gson;
public GsonProvider() {
}
private Gson getGson() {
if (gson == null) {
final GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
}
return gson;
}
#Override
public boolean isReadable(Class<?> type, Type genericType,
java.lang.annotation.Annotation[] annotations, MediaType mediaType) {
return true;
}
#Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
try (InputStreamReader streamReader = new InputStreamReader(entityStream, UTF_8)) {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
return getGson().fromJson(streamReader, jsonType);
}
}
#Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
#Override
public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
#Override
public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
try (OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8)) {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
getGson().toJson(object, jsonType, writer);
}
}
}
Output in tests:
Container{id=a9e3a67979d392a0e48d534db5184ce717b0629c4255d4dbc1373f5a9140df51, command=/bin/sh -c /usr/sbin/sshd -D, image=frantiseks/apac:latest, created=1388002251, status=Up About an hour, ports=[Lcz.utb.fai.apac.entity.Port;#69ac536b, size=0, sizeRootFs=0, names=[Ljava.lang.String;#3098cc00}
Output from deployed application:
[Container{id=null, command=null, image=null, created=0, status=null, ports=null, size=0, sizeRootFs=0, names=null}, Container{id=null, command=null, image=null, created=0, status=null, ports=null, size=0, sizeRootFs=0, names=null}]
So could someone tell me why it do not work in glassfish? Or what I am doing wrong?
Thanks.