Values changes from double to integer when saving to mysql database - mysql

Entities:
Simulation:
package Simulations.Entity;
import lombok.*;
import javax.persistence.*;
import java.util.List;
#Builder
#Table
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class Simulation {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private Long id;
#Column(name = "N")
private String simulation_Name;
#Column(name = "P")
private Double population_Size;
#Column(name = "I")
private Double initial_Infected_Number;
#Column(name = "R")
private Double how_Many_One_Infects;
#Column(name = "M")
private Double mortality_Rate;
#Column(name = "Ti")
private Double number_Of_Days_To_Recovery;
#Column(name = "Tm")
private Double number_Of_Days_To_Death;
#Column(name = "Ts")
private Double simulation_Time;
#OneToMany(mappedBy = "simulation", cascade = CascadeType.REMOVE)
private List<SimulationsValues> simulationsValues;
}
SimulationValues:
package Simulations.Entity;
import lombok.*;
import javax.persistence.*;
#Builder
#Table
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class SimulationsValues {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column
private Long id;
#Column(name = "Day")
private Double day;
#Column(name = "Pi")
private Double number_Of_Infected;
#Column(name = "Pv")
private Double healthy_Prone_To_Infection;
#Column(name = "Pm")
private Double dead;
#Column(name = "Pr")
private Double regained_Health_And_Immunity;
#ManyToOne
#JoinColumn(name = "simulation_id", referencedColumnName = "id")
private Simulation simulation;
}
Logic calss:
package Simulations.Services;
import Simulations.Entity.Simulation;
import Simulations.Entity.SimulationsValues;
import Simulations.Repositories.SimulationRepository;
import Simulations.Repositories.SimulationsValuesRepository;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
#RequiredArgsConstructor
#Component
#Aspect
public class EachRemainingDayService {
private final SimulationRepository simulationRepository;
private final SimulationsValuesRepository simulationsValuesRepository;
#Pointcut("#annotation(Simulations.Annotations.MyAnnotation)")
public void MyAnnotationMethod() {
}
public List<Simulation> getSimulations() {
List<Simulation> listOdIds = new ArrayList<>(simulationRepository.findAll());
listOdIds.sort(Comparator.comparing(Simulation::getId));
return listOdIds;
}
public List<SimulationsValues> getSimulationsValues() {
List<SimulationsValues> listOdIdsOfValues = new ArrayList<>(simulationsValuesRepository.findAll());
listOdIdsOfValues.sort(Comparator.comparing(SimulationsValues::getId));
return listOdIdsOfValues;
}
//3 zapis wynikow do bazy
#After("MyAnnotationMethod()")// zmienilem z Before
public void SimulationParametersForRemainingDays() {
var sim = getSimulations();
var newestSimulation = simulationRepository.getById(sim.get(sim.size() - 1).getId());
var simVal = getSimulationsValues();
var newestSimulationsVal = simulationsValuesRepository
.getById(simVal.get(simVal.size() - 1).getId());
//zapisanie do bazy TO LOGIKA!!!
for (double i = 2; i <= newestSimulation.getSimulation_Time(); i++) {
if (newestSimulationsVal.getHealthy_Prone_To_Infection() <= 0) {
break;
}
if (i >= newestSimulation.getNumber_Of_Days_To_Death()
&& i < newestSimulation.getNumber_Of_Days_To_Recovery()) {
sim = getSimulations();
newestSimulation = simulationRepository.getById(sim.get(sim.size() - 1).getId());
simVal = getSimulationsValues();
newestSimulationsVal = simulationsValuesRepository
.getById(simVal.get(simVal.size() - 1).getId());
SimulationsValues simulation_values;
Simulation finalNewestSimulation1 = newestSimulation;
double finalI = i;
simulation_values = SimulationsValues.builder()
.day(i)
.healthy_Prone_To_Infection(newestSimulation.getPopulation_Size() -
(((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()
+ newestSimulationsVal.getNumber_Of_Infected())))
.number_Of_Infected((((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()
+ newestSimulationsVal.getNumber_Of_Infected())//L24
- (newestSimulation.getMortality_Rate() * (double) ((simulationsValuesRepository
.findAll().stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))
.collect(Collectors.toList()).get((int) (simulationsValuesRepository.findAll().stream()
.filter(e -> e.getDay() == (finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))).count() - 1).getNumber_Of_Infected()))))//V24
.regained_Health_And_Immunity(0d)// Z24
.dead((newestSimulation.getMortality_Rate() * (double) ((simulationsValuesRepository
.findAll().stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))
.collect(Collectors.toList()).get((int) (simulationsValuesRepository.findAll().stream()
.filter(e -> e.getDay() == (finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))).count() - 1).getNumber_Of_Infected()))
- newestSimulationsVal.getDead())//V24
.build();
var simId = simulationsValuesRepository.save(simulation_values);
simId.setSimulation(newestSimulation);//dodane
var simVal2 = newestSimulation.getSimulationsValues();
simVal2.add(simId);
newestSimulation.setSimulationsValues(simVal2);
simulationRepository.save(newestSimulation);
} else if (i >= newestSimulation.getNumber_Of_Days_To_Recovery()) {
sim = getSimulations();
newestSimulation = simulationRepository.getById(sim.get(sim.size() - 1).getId());
simVal = getSimulationsValues();
newestSimulationsVal = simulationsValuesRepository
.getById(simVal.get(simVal.size() - 1).getId());
Simulation finalNewestSimulation1 = newestSimulation;
double finalI = i;
SimulationsValues simulation_values;
simulation_values = SimulationsValues.builder()
.day(i)
.healthy_Prone_To_Infection(newestSimulation.getPopulation_Size() -
((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()))
.number_Of_Infected(((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()
+ newestSimulationsVal.getNumber_Of_Infected())//L24
- (newestSimulation.getMortality_Rate() * (double) ((simulationsValuesRepository
.findAll().stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))
.collect(Collectors.toList()).get((int) (simulationsValuesRepository.findAll().stream()
.filter(e -> e.getDay() == (finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))).count() - 1).getNumber_Of_Infected())//V24
- (((1 - newestSimulation.getMortality_Rate()) * (simulationsValuesRepository
.findAll().stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Recovery()))
.collect(Collectors.toList()).get((int) (simulationsValuesRepository.findAll().stream()
.filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Recovery())).count() - 1)
.getNumber_Of_Infected()))//Z24
))
.regained_Health_And_Immunity((1 - newestSimulation.getMortality_Rate()) *
(simulationsValuesRepository.findAll()
.stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Recovery()))
.collect(Collectors.toList()).get((int) (simulationsValuesRepository.findAll()
.stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Recovery())).count() - 1)
.getNumber_Of_Infected())// Z24
.dead((newestSimulation.getMortality_Rate() * (double) ((simulationsValuesRepository.findAll()
.stream().filter(e -> e.getDay() == finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))
.collect(Collectors.toList()).get((int) (simulationsValuesRepository.findAll().stream()
.filter(e -> e.getDay() == (finalI + 1 - finalNewestSimulation1
.getNumber_Of_Days_To_Death()))).count()1).getNumber_Of_Infected()))
- newestSimulationsVal.getDead())//V24
.build();
var simId = simulationsValuesRepository.save(simulation_values);
simId.setSimulation(newestSimulation);//dodane
var simVal2 = newestSimulation.getSimulationsValues();
simVal2.add(simId);
newestSimulation.setSimulationsValues(simVal2);
simulationRepository.save(newestSimulation);
} else if (i == 2) {
sim = getSimulations();
newestSimulation = simulationRepository.getById(sim.get(sim.size() - 1).getId());
simVal = getSimulationsValues();
newestSimulationsVal = simulationsValuesRepository
.getById(simVal.get(simVal.size() - 1).getId());
SimulationsValues simulation_values;
simulation_values = SimulationsValues.builder()
.day(i)
.healthy_Prone_To_Infection(newestSimulationsVal.getHealthy_Prone_To_Infection() -
((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()))
.number_Of_Infected((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()
+ newestSimulationsVal.getNumber_Of_Infected())
.regained_Health_And_Immunity(0d)
.dead(0d)
.build();
var simId2 = simulationsValuesRepository.save(simulation_values);
simId2.setSimulation(newestSimulation);//dodane
var simVal2 = newestSimulation.getSimulationsValues();
simVal2.add(simId2);
newestSimulation.setSimulationsValues(simVal2);
simulationRepository.save(newestSimulation);
} else {
sim = getSimulations();
newestSimulation = simulationRepository.getById(sim.get(sim.size() - 1).getId());
simVal = getSimulationsValues();
newestSimulationsVal = simulationsValuesRepository
.getById(simVal.get(simVal.size() - 1).getId());
SimulationsValues simulation_values;
simulation_values = SimulationsValues.builder()
.day(i)
.healthy_Prone_To_Infection(newestSimulationsVal.getHealthy_Prone_To_Infection() -
((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()))
.number_Of_Infected((newestSimulation.getHow_Many_One_Infects())
* newestSimulationsVal.getNumber_Of_Infected()
+ newestSimulationsVal.getNumber_Of_Infected())
.regained_Health_And_Immunity(0d)
.dead(0d)
.build();
var simId2 = simulationsValuesRepository.save(simulation_values);
simId2.setSimulation(newestSimulation);//dodane
var simVal2 = newestSimulation.getSimulationsValues();
simVal2.add(simId2);
newestSimulation.setSimulationsValues(simVal2);
simulationRepository.save(newestSimulation);
}
}
}
}
ViewModel:
package Simulations.ViewModels;
import Simulations.Annotations.GreaterThan;
import Simulations.Entity.SimulationsValues;
import lombok.*;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
#Builder
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#GreaterThan(message = "field number of days to death can not be equal or bigger than field days to recovery")
public class SimulationViewModel {
private Long id;
#NotEmpty(message = "field can not be empty")
private String simulation_Name;
#NotNull(message = "field can not be empty")
#DecimalMax("10000000000.0")
#DecimalMin("0.0")
private Double population_Size;
private Double initial_Infected_Number;
#NotNull(message = "field can not be empty")
private Double how_Many_One_Infects;
#NotNull(message = "field can not be empty")
#DecimalMax("1.0")
#DecimalMin("0.001")
private Double mortality_Rate;
private #NotNull(message = "field can not be empty") #DecimalMin("1.0")
Double number_Of_Days_To_Recovery;
private #NotNull(message = "field can not be empty") #DecimalMin("1.0")
Double number_Of_Days_To_Death;
private #NotNull(message = "field can not be empty")
Double simulation_Time;
List<SimulationsValues> simulationsValues = new ArrayList<>();
}
Hi, I have a roblem. When I create a simulationValues object (using builder) it's fields have double values as intended but when I save this object to database and look at thoese values in database (MySql) thoese values are presented as Integers i.e. without values after comma, for example when I debug my code I see that "dead" field has in 12 iteration value 0.9 but it is saved to database as 1. Why is that? I don;t do any casting and all I use for this calculations are doubles as well as all fields n SimulationValues class and SimulationViewModel are doubles. Why when saving field changes types?Thanks in advance

All columns in MySql were bigint type instead of double as I made them in coresponding entity, changed them to BigDecimal and everything works fine.

Related

How to organize database columns in same order as specified in model on Hibernate? [duplicate]

This (should) be a rather simple thing to do, however I am struggling.
I want a table to be generated like this:
id
organizationNumber
name
However, when I look in the database, I see that the ordering is wrong. Does anybody know how I can force hibernate/jpa to generate the table with correct ordering?
desc Organization;
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| organizationNumber | varchar(255) | NO | UNI | NULL | |
+--------------------+--------------+------+-----+---------+----------------+
This is how my entity bean looks like:
#Entity
#NamedQuery(name = "allOrganizations", query = "SELECT org FROM Organization org order by name")
public class Organization {
private Long id;
private String organizationNumber;
private String name;
public Organization() {
}
public Organization(String name) {
this.name = name;
}
#Id
#GeneratedValue
public Long getId() {
return id;
}
#SuppressWarnings("unused")
private void setId(Long id) {
this.id = id;
}
#NotEmpty
#Column(unique=true, nullable=false)
public String getOrganizationNumber() {
return organizationNumber;
}
public void setOrganizationNumber(String organizationNumber) {
this.organizationNumber = organizationNumber;
}
#NotEmpty
#Column(nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return this.name + " " + this.organizationNumber;
}
}
Hibernate generates columns in alphabetical order. According to this post the reason is given as:
It is sorted to ensurce deterministic
ordering across clusters.
We can't rely on the vm to return the
methods in the same order every time
so we had to do something.
Apparently it used to be in the order of occurrence but this changed between 3.2.0 GA and 3.2.1 GA.
I also found Schema auto generation creates columns in alphabetical order for compound primary keys and this seems to be like your problem. This ticket is about the order changing in primary keys and that negatively impacts index performance.
There is no fix for this other than a workaround of naming the columns in such a way that they come out in the correct order (no, I'm not kidding).
I have the same problem. Finally, I found the solution.
Find your External Libraries about hibernate core and find the org.hibernate.cfg.PropertyContainer class and copy the content.
In your root folder create the org.hibernate.cfg package and PropertyContainer class.
Paste the org.hibernate.cfg.PropertyContainer content and replace all TreeMap to LinkedHashMap in your create PropertyContainer class.
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
// $Id$
package org.hibernate.cfg;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.persistence.Access;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.annotations.ManyToAny;
import org.hibernate.annotations.Target;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.boot.jaxb.Origin;
import org.hibernate.boot.jaxb.SourceType;
import org.hibernate.cfg.annotations.HCANNHelper;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.jboss.logging.Logger;
/**
* A helper class to keep the {#code XProperty}s of a class ordered by access type.
*
* #author Hardy Ferentschik
*/
class PropertyContainer {
//
// static {
// System.setProperty("jboss.i18n.generate-proxies", "true");
// }
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, PropertyContainer.class.getName());
/**
* The class for which this container is created.
*/
private final XClass xClass;
private final XClass entityAtStake;
/**
* Holds the AccessType indicated for use at the class/container-level for cases where persistent attribute
* did not specify.
*/
private final AccessType classLevelAccessType;
private final TreeMap<String, XProperty> persistentAttributeMap;
PropertyContainer(XClass clazz, XClass entityAtStake, AccessType defaultClassLevelAccessType) {
this.xClass = clazz;
this.entityAtStake = entityAtStake;
if ( defaultClassLevelAccessType == AccessType.DEFAULT ) {
// this is effectively what the old code did when AccessType.DEFAULT was passed in
// to getProperties(AccessType) from AnnotationBinder and InheritanceState
defaultClassLevelAccessType = AccessType.PROPERTY;
}
AccessType localClassLevelAccessType = determineLocalClassDefinedAccessStrategy();
assert localClassLevelAccessType != null;
this.classLevelAccessType = localClassLevelAccessType != AccessType.DEFAULT
? localClassLevelAccessType
: defaultClassLevelAccessType;
assert classLevelAccessType == AccessType.FIELD || classLevelAccessType == AccessType.PROPERTY;
this.persistentAttributeMap = new TreeMap<String, XProperty>();
final List<XProperty> fields = xClass.getDeclaredProperties( AccessType.FIELD.getType() );
final List<XProperty> getters = xClass.getDeclaredProperties( AccessType.PROPERTY.getType() );
preFilter( fields, getters );
final Map<String,XProperty> persistentAttributesFromGetters = new HashMap<String, XProperty>();
collectPersistentAttributesUsingLocalAccessType(
persistentAttributeMap,
persistentAttributesFromGetters,
fields,
getters
);
collectPersistentAttributesUsingClassLevelAccessType(
persistentAttributeMap,
persistentAttributesFromGetters,
fields,
getters
);
}
private void preFilter(List<XProperty> fields, List<XProperty> getters) {
Iterator<XProperty> propertyIterator = fields.iterator();
while ( propertyIterator.hasNext() ) {
final XProperty property = propertyIterator.next();
if ( mustBeSkipped( property ) ) {
propertyIterator.remove();
}
}
propertyIterator = getters.iterator();
while ( propertyIterator.hasNext() ) {
final XProperty property = propertyIterator.next();
if ( mustBeSkipped( property ) ) {
propertyIterator.remove();
}
}
}
private void collectPersistentAttributesUsingLocalAccessType(
TreeMap<String, XProperty> persistentAttributeMap,
Map<String,XProperty> persistentAttributesFromGetters,
List<XProperty> fields,
List<XProperty> getters) {
// Check fields...
Iterator<XProperty> propertyIterator = fields.iterator();
while ( propertyIterator.hasNext() ) {
final XProperty xProperty = propertyIterator.next();
final Access localAccessAnnotation = xProperty.getAnnotation( Access.class );
if ( localAccessAnnotation == null
|| localAccessAnnotation.value() != javax.persistence.AccessType.FIELD ) {
continue;
}
propertyIterator.remove();
persistentAttributeMap.put( xProperty.getName(), xProperty );
}
// Check getters...
propertyIterator = getters.iterator();
while ( propertyIterator.hasNext() ) {
final XProperty xProperty = propertyIterator.next();
final Access localAccessAnnotation = xProperty.getAnnotation( Access.class );
if ( localAccessAnnotation == null
|| localAccessAnnotation.value() != javax.persistence.AccessType.PROPERTY ) {
continue;
}
propertyIterator.remove();
final String name = xProperty.getName();
// HHH-10242 detect registration of the same property getter twice - eg boolean isId() + UUID getId()
final XProperty previous = persistentAttributesFromGetters.get( name );
if ( previous != null ) {
throw new org.hibernate.boot.MappingException(
LOG.ambiguousPropertyMethods(
xClass.getName(),
HCANNHelper.annotatedElementSignature( previous ),
HCANNHelper.annotatedElementSignature( xProperty )
),
new Origin( SourceType.ANNOTATION, xClass.getName() )
);
}
persistentAttributeMap.put( name, xProperty );
persistentAttributesFromGetters.put( name, xProperty );
}
}
private void collectPersistentAttributesUsingClassLevelAccessType(
TreeMap<String, XProperty> persistentAttributeMap,
Map<String,XProperty> persistentAttributesFromGetters,
List<XProperty> fields,
List<XProperty> getters) {
if ( classLevelAccessType == AccessType.FIELD ) {
for ( XProperty field : fields ) {
if ( persistentAttributeMap.containsKey( field.getName() ) ) {
continue;
}
persistentAttributeMap.put( field.getName(), field );
}
}
else {
for ( XProperty getter : getters ) {
final String name = getter.getName();
// HHH-10242 detect registration of the same property getter twice - eg boolean isId() + UUID getId()
final XProperty previous = persistentAttributesFromGetters.get( name );
if ( previous != null ) {
throw new org.hibernate.boot.MappingException(
LOG.ambiguousPropertyMethods(
xClass.getName(),
HCANNHelper.annotatedElementSignature( previous ),
HCANNHelper.annotatedElementSignature( getter )
),
new Origin( SourceType.ANNOTATION, xClass.getName() )
);
}
if ( persistentAttributeMap.containsKey( name ) ) {
continue;
}
persistentAttributeMap.put( getter.getName(), getter );
persistentAttributesFromGetters.put( name, getter );
}
}
}
public XClass getEntityAtStake() {
return entityAtStake;
}
public XClass getDeclaringClass() {
return xClass;
}
public AccessType getClassLevelAccessType() {
return classLevelAccessType;
}
public Collection<XProperty> getProperties() {
assertTypesAreResolvable();
return Collections.unmodifiableCollection( persistentAttributeMap.values() );
}
private void assertTypesAreResolvable() {
for ( XProperty xProperty : persistentAttributeMap.values() ) {
if ( !xProperty.isTypeResolved() && !discoverTypeWithoutReflection( xProperty ) ) {
String msg = "Property " + StringHelper.qualify( xClass.getName(), xProperty.getName() ) +
" has an unbound type and no explicit target entity. Resolve this Generic usage issue" +
" or set an explicit target attribute (eg #OneToMany(target=) or use an explicit #Type";
throw new AnnotationException( msg );
}
}
}
//
// private void considerExplicitFieldAndPropertyAccess() {
// for ( XProperty property : fieldAccessMap.values() ) {
// Access access = property.getAnnotation( Access.class );
// if ( access == null ) {
// continue;
// }
//
// // see "2.3.2 Explicit Access Type" of JPA 2 spec
// // the access type for this property is explicitly set to AccessType.FIELD, hence we have to
// // use field access for this property even if the default access type for the class is AccessType.PROPERTY
// AccessType accessType = AccessType.getAccessStrategy( access.value() );
// if (accessType == AccessType.FIELD) {
// propertyAccessMap.put(property.getName(), property);
// }
// else {
// LOG.debug( "Placing #Access(AccessType.FIELD) on a field does not have any effect." );
// }
// }
//
// for ( XProperty property : propertyAccessMap.values() ) {
// Access access = property.getAnnotation( Access.class );
// if ( access == null ) {
// continue;
// }
//
// AccessType accessType = AccessType.getAccessStrategy( access.value() );
//
// // see "2.3.2 Explicit Access Type" of JPA 2 spec
// // the access type for this property is explicitly set to AccessType.PROPERTY, hence we have to
// // return use method access even if the default class access type is AccessType.FIELD
// if (accessType == AccessType.PROPERTY) {
// fieldAccessMap.put(property.getName(), property);
// }
// else {
// LOG.debug( "Placing #Access(AccessType.PROPERTY) on a field does not have any effect." );
// }
// }
// }
// /**
// * Retrieves all properties from the {#code xClass} with the specified access type. This method does not take
// * any jpa access rules/annotations into account yet.
// *
// * #param access The access type - {#code AccessType.FIELD} or {#code AccessType.Property}
// *
// * #return A maps of the properties with the given access type keyed against their property name
// */
// private TreeMap<String, XProperty> initProperties(AccessType access) {
// if ( !( AccessType.PROPERTY.equals( access ) || AccessType.FIELD.equals( access ) ) ) {
// throw new IllegalArgumentException( "Access type has to be AccessType.FIELD or AccessType.Property" );
// }
//
// //order so that property are used in the same order when binding native query
// TreeMap<String, XProperty> propertiesMap = new TreeMap<String, XProperty>();
// List<XProperty> properties = xClass.getDeclaredProperties( access.getType() );
// for ( XProperty property : properties ) {
// if ( mustBeSkipped( property ) ) {
// continue;
// }
// // HHH-10242 detect registration of the same property twice eg boolean isId() + UUID getId()
// XProperty oldProperty = propertiesMap.get( property.getName() );
// if ( oldProperty != null ) {
// throw new org.hibernate.boot.MappingException(
// LOG.ambiguousPropertyMethods(
// xClass.getName(),
// HCANNHelper.annotatedElementSignature( oldProperty ),
// HCANNHelper.annotatedElementSignature( property )
// ),
// new Origin( SourceType.ANNOTATION, xClass.getName() )
// );
// }
//
// propertiesMap.put( property.getName(), property );
// }
// return propertiesMap;
// }
private AccessType determineLocalClassDefinedAccessStrategy() {
AccessType classDefinedAccessType;
AccessType hibernateDefinedAccessType = AccessType.DEFAULT;
AccessType jpaDefinedAccessType = AccessType.DEFAULT;
org.hibernate.annotations.AccessType accessType = xClass.getAnnotation( org.hibernate.annotations.AccessType.class );
if ( accessType != null ) {
hibernateDefinedAccessType = AccessType.getAccessStrategy( accessType.value() );
}
Access access = xClass.getAnnotation( Access.class );
if ( access != null ) {
jpaDefinedAccessType = AccessType.getAccessStrategy( access.value() );
}
if ( hibernateDefinedAccessType != AccessType.DEFAULT
&& jpaDefinedAccessType != AccessType.DEFAULT
&& hibernateDefinedAccessType != jpaDefinedAccessType ) {
throw new MappingException(
"#AccessType and #Access specified with contradicting values. Use of #Access only is recommended. "
);
}
if ( hibernateDefinedAccessType != AccessType.DEFAULT ) {
classDefinedAccessType = hibernateDefinedAccessType;
}
else {
classDefinedAccessType = jpaDefinedAccessType;
}
return classDefinedAccessType;
}
private static boolean discoverTypeWithoutReflection(XProperty p) {
if ( p.isAnnotationPresent( OneToOne.class ) && !p.getAnnotation( OneToOne.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( OneToMany.class ) && !p.getAnnotation( OneToMany.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( ManyToOne.class ) && !p.getAnnotation( ManyToOne.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( ManyToMany.class ) && !p.getAnnotation( ManyToMany.class )
.targetEntity()
.equals( void.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( ManyToAny.class ) ) {
if ( !p.isCollection() && !p.isArray() ) {
throw new AnnotationException( "#ManyToAny used on a non collection non array property: " + p.getName() );
}
return true;
}
else if ( p.isAnnotationPresent( Type.class ) ) {
return true;
}
else if ( p.isAnnotationPresent( Target.class ) ) {
return true;
}
return false;
}
private static boolean mustBeSkipped(XProperty property) {
//TODO make those hardcoded tests more portable (through the bytecode provider?)
return property.isAnnotationPresent( Transient.class )
|| "net.sf.cglib.transform.impl.InterceptFieldCallback".equals( property.getType().getName() )
|| "org.hibernate.bytecode.internal.javassist.FieldHandler".equals( property.getType().getName() );
}
}
Fixed the Organization class.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Organization {
#Id
#GeneratedValue
private Long id;
#Column(unique = true, nullable = false)
private String organizationNumber;
#Column(nullable = false)
private String name;
public Organization() {
}
public Organization(String name) {
this.name = name;
}
public Long getId() {
return id;
}
#SuppressWarnings("unused")
public void setId(Long id) {
this.id = id;
}
public String getOrganizationNumber() {
return organizationNumber;
}
public void setOrganizationNumber(String organizationNumber) {
this.organizationNumber = organizationNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return this.name + " " + this.organizationNumber;
}
}
Start the Spring Boot App. See the result in the console.
Hibernate: create table organization (id bigint not null, organization_number varchar(255) not null, name varchar(255) not null, primary key (id)) engine=InnoDB
In the database see the desc result.
mysql> desc organization;
+---------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| organization_number | varchar(255) | NO | UNI | NULL | |
| name | varchar(255) | NO | | NULL | |
+---------------------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
Supplement on Inheritance
If you want use the inherit some parent class like Auditing class. The above answer is not enough.
You can copy InheritanceState.class like above approach and create the InheritanceState.class into org.hibernate.cfg package.
Modify the two line, just fixed the sorting.
public class InheritanceState {
// ...
private void getMappedSuperclassesTillNextEntityOrdered() {
//ordered to allow proper messages on properties subclassing
XClass currentClassInHierarchy = clazz;
InheritanceState superclassState;
do {
// mark this ↓↓↓↓↓
// classesToProcessForMappedSuperclass.add( 0, currentClassInHierarchy );
// fixed the sorting, add this ↓↓↓↓↓
classesToProcessForMappedSuperclass.add( currentClassInHierarchy );
// ...
}
// ...
}
private void addMappedSuperClassInMetadata(PersistentClass persistentClass) {
//add #MappedSuperclass in the metadata
// classes from 0 to n-1 are #MappedSuperclass and should be linked
org.hibernate.mapping.MappedSuperclass mappedSuperclass = null;
final InheritanceState superEntityState =
InheritanceState.getInheritanceStateOfSuperEntity( clazz, inheritanceStatePerClass );
PersistentClass superEntity =
superEntityState != null ?
buildingContext.getMetadataCollector().getEntityBinding( superEntityState.getClazz().getName() ) :
null;
final int lastMappedSuperclass = classesToProcessForMappedSuperclass.size() - 1;
// mark this ↓↓↓↓↓
// for ( int index = 0; index < lastMappedSuperclass; index++ ) {
// fixed the sorting, add this ↓↓↓↓↓
for ( int index = lastMappedSuperclass; index > 0; index-- ) {
// ...
}
// ...
}
}
The demo class.
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity {
#CreatedBy
#Column(name = "created_by")
private String createdBy;
#LastModifiedBy
#Column(name = "last_modified_by")
private String lastModifiedBy;
#LastModifiedDate
#Column(name = "update_time")
private ZonedDateTime updatedTime;
#CreatedDate
#Column(name = "create_time")
private ZonedDateTime createTime;
}
#Entity
public class OrganizationAudit extends AuditableEntity {
// same field with Organization.class...
}
In console result.
create table organization_audit (id bigint not null, organization_number varchar(255) not null, name varchar(255) not null, created_by varchar(255), last_modified_by varchar(255), update_time datetime, create_time datetime, primary key (id)) engine=InnoDB
In database result.
mysql> desc organization_audit;
+---------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| organization_number | varchar(255) | NO | UNI | NULL | |
| name | varchar(255) | NO | | NULL | |
| created_by | varchar(255) | YES | | NULL | |
| last_modified_by | varchar(255) | YES | | NULL | |
| update_time | datetime | YES | | NULL | |
| create_time | datetime | YES | | NULL | |
+---------------------+--------------+------+-----+---------+-------+
7 rows in set (0.00 sec)
The sample project is here.
You can set the order you want whenever you can change the internal name of the class members, since the order of the columns is taken from the field name, not from the getter, setter, or column.
Thus, if the class members are private (as desired), you should only list them (for example by prefixing them with "a_", "b_", "c_", ...) without changing either the getters, the setters, or the column names.
For example, the following class definition:
#Id
#Column(name = "parent")
UUID parent;
#Id
#Column(name = "type", length = 10)
String type;
#Id
#Column(name = "child")
UUID child;
It generates the following table:
Column | Type | Collation | Nullable | Default
-----------+-----------------------+-----------+----------+---------
child | uuid | | not null |
parent | uuid | | not null |
type | character varying(10) | | not null |
Indexes:
"...whatever..." PRIMARY KEY, btree (child, parent, type)
Which is not efficient because normally we will search by parent and type of relationship to obtain the children.
We can change the private names without affecting the rest of the implementation by doing:
#Id
#Column(name = "parent")
UUID a_parent;
#Id
#Column(name = "type", length = 10)
String b_type;
#Id
#Column(name = "child")
UUID c_child;
public UUID getParent() { return a_parent; }
public UUID getChild() { return c_child; }
public String getType() { return b_type; }
public void setParent(UUID parent) { a_parent = parent; }
public void setChild(UUID child) { c_child = child; }
public void setType(String type) { b_type = type; }
In that it has now been generated:
Column | Type | Collation | Nullable | Default
-----------+-----------------------+-----------+----------+---------
parent | uuid | | not null |
type | character varying(10) | | not null |
child | uuid | | not null |
Indexes:
"...whatever..." PRIMARY KEY, btree (parent, type, child)
Of course it is not best to depend on the internal lexicographical order of the class members but I do not see a better solution.
DataNucleus allows the extension specifying the position for schema generation, FWIW.
Just create that Table using create statement in your database and use Hibernate to insert a value into Table
Only to resolve the inheritance for the auditable class as an example,
JPA doesn't respect the alpha order, will create first the auditable columns, in this case, for the columns of the auditable class to be created last!
You need to comment #MappedSuperclass, then run in sequence with 'create', then uncomment and run with 'update' for the 'ddl-auto' option.

Spring boot - MySQL - MySQLSyntaxErrorException: Unknown column 'product0_.product_id' in 'field list'

After going through several threads similar to my problem with unsuccessful result, I am posting this. I get the error as in the heading. Below is my model file Product
Product.java
package com.ms.Products;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "product")
public class Product {
#Id
#Column(name = "ProductId")
private String ProductId = null;
#Column(name = "ProductName")
private String ProductName = null;
#Column(name = "ProductCategory")
private String ProductCategory = null;
#Column(name = "Price")
private double Price = 0;
#Column(name = "Quantity")
private int Quantity = 0;
public Product() {
}
public Product(String productId, String productName, String prodcutCategory, double princeInEuros,
int quantityAvailable) {
this.ProductId = productId;
this.ProductName = productName;
this.ProductCategory = prodcutCategory;
this.Price = princeInEuros;
this.Quantity = quantityAvailable;
}
public String getProductId() {
return ProductId;
}
public void setProductId(String productId) {
this.ProductId = productId;
}
public String getProductName() {
return ProductName;
}
public void setProductName(String productName) {
this.ProductName = productName;
}
public String getProdcutCategory() {
return ProductCategory;
}
public void setProdcutCategory(String prodcutCategory) {
this.ProductCategory = prodcutCategory;
}
public double getPrinceInEuros() {
return Price;
}
public void setPrinceInEuros(double princeInEuros) {
this.Price = princeInEuros;
}
public int getQuantityAvailable() {
return Quantity;
}
public void setQuantityAvailable(int quantityAvailable) {
this.Quantity = quantityAvailable;
}
}
Database schema
mysql> SHOW TABLES;
+--------------------+
| Tables_in_products |
+--------------------+
| category |
| product |
| users |
+--------------------
+
My product table
mysql> select * from product;
+-----------+-------------+-----------------+-------+----------+
| ProductId | ProductName | ProductCategory | Price | Quantity |
+-----------+-------------+-----------------+-------+----------+
| 1 | Cheese | L | 1.65 | 25 |
| 2 | Milk | L | 0.5 | 55 |
+-----------+-------------+-----------------+-------+----------+
2 rows in set (0.00 sec)
my application.properties
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
spring.datasource.url=jdbc:mysql://localhost/Products
spring.datasource.username=root
spring.datasource.password=sj
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Please any help me with an idea on what am i missing here or what i need to do here?
I get this error while trying to add or view. M controller code
PRoductController.java
#Autowired
private ProductService productService;
#RequestMapping("/allProducts")
public List<Product> getAllProducts(){
return productService.getAllProducts();
}
#RequestMapping("/addProduct")
public String addProduct(Product productFromView) {
Product product = new Product();
product.setProductId("3");
product.setProductName("Salt");
product.setProdcutCategory("L");
product.setPrinceInEuros(0.65);
product.setQuantityAvailable(20);
productService.addProduct(product);
return "Product Added";
}
ProductService.java
public List<Product> getAllProducts(){
List<Product> products = new ArrayList<Product>();
productDao.findAll().forEach(products::add);
return products;
}
public void addProduct(Product product) {
productDao.save(product);
}

Linq + nested GroupBy

We are using mySQL with WCF Restful service, we want to fetch our database content PACKAGEID wise...as mentioned below:
PackageId=2
{
StartRange = 1;
EndRange = 100;
IsDiscountAndChargeInPer = 1;
Discount =10;
ServiceCharge = 20;![enter image description here][1]
},
{
StartRange =101;
EndRange = 500;
IsDiscountAndChargeInPer = 1;
Discount =10;
ServiceCharge = 20;
}
PackageId=3
{
StartRange = 1;
EndRange = 100;
IsDiscountAndChargeInPer = 1;
Discount =10;
ServiceCharge = 20;
}
We have created a Result class to return result from out wcf service...for above service we have result class defined as below
[DataContract]
public class PackagePointRangeConfigurationResult : ResultBase
{
[DataMember]
public List<PackagePointRangeResult> Result;
}
public class PackagePointRangeResult
{
public int PackageId { get; set; }
public List<PointPlanInfo> Result { get; set; }
}
For fetching record we use following linq query:
var result = (from planinfo in db.mst_pointplan_info
join entityType in db.mst_entity_type
on planinfo.entityId equals entityType.id
where planinfo.entityId == entityId
&& planinfo.is_deleted != true
&& planinfo.system_id == systemId
&& entityType.enity_enum_id == entityId
group planinfo by planinfo.package_id into gplan
select new PackagePointRangeConfigurationResult
{
Result = (from planinfo in gplan
select new PackagePointRangeResult
{
PackageId = planinfo.package_id,
PointPlanInfo = (from pointPlanInfo in gplan
select new PointPlanInfo
{
StartRange = planinfo.start_range,
EndRange = planinfo.end_range,
IsDiscountAndChargeInPer = planinfo.is_discount_and_charge_in_per,
Discount = planinfo.discount,
ServiceCharge = planinfo.servicecharge,
AtonMerchantShare =planinfo.aton_merchant_share,
CommunityShare = planinfo.community_share
}).ToList()
}).ToList()
}).FirstOrDefault();
But it gives me below error:
LINQ to Entities does not recognize the method 'System.Collections.Generic.List1[PointPlanInfo] ToList[PointPlanInfo](System.Collections.Generic.IEnumerable1[PointPlanInfo])' method, and this method cannot be translated into a store expression.

ensure uniqueness (distinct record) with JPQL or SQL? Or both?

How can I prevent TopLink from duplicating existing data? Is it even a good idea to do that with Java code, or should that be built into the database and let inserts fail?
In this case, I want to ensure that newsgroups.newsgroup is unique and that articles.header_id_string is also unique.
Probably the best approach would be to simply run a query for uniqueness in Java JPQL?
Schema:
mysql>
mysql> show tables;
+---------------------+
| Tables_in_nntp |
+---------------------+
| articles |
| newsgroups |
| newsgroups_articles |
+---------------------+
3 rows in set (0.01 sec)
mysql> describe newsgroups;
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| newsgroup | text | NO | | NULL | |
+-----------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> describe articles;
+------------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| subject | text | NO | | NULL | |
| content | text | NO | | NULL | |
| number | int(11) | NO | | NULL | |
| sent | date | NO | | NULL | |
| header_id_string | text | NO | | NULL | |
+------------------+---------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
mysql> describe newsgroups_articles;
+--------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| article_id | int(11) | NO | | NULL | |
| newsgroup_id | int(11) | NO | MUL | NULL | |
+--------------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql>
The Newsgroup entity:
package net.bounceme.dur.usenet.model;
import java.io.Serializable;
import javax.mail.Folder;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "newsgroups", catalog = "nntp", schema = "")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Newsgroups.findAll", query = "SELECT n FROM Newsgroup n"),
#NamedQuery(name = "Newsgroups.findById", query = "SELECT n FROM Newsgroup n WHERE n.id = :id")})
public class Newsgroup implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id", nullable = false)
private Integer id;
#Basic(optional = false)
#Lob
#Column(name = "newsgroup", nullable = false, length = 65535)
private String newsgroup;
public Newsgroup() {
}
public Newsgroup(Folder f){
newsgroup = f.getFullName();
}
public Newsgroup(Integer id) {
this.id = id;
}
public Newsgroup(Integer id, String newsgroup) {
this.id = id;
this.newsgroup = newsgroup;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNewsgroup() {
return newsgroup;
}
public void setNewsgroup(String newsgroup) {
this.newsgroup = newsgroup;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Newsgroup)) {
return false;
}
Newsgroup other = (Newsgroup) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "net.bounceme.dur.usenet.model.Newsgroups[ id=" + id + " ]";
}
}
And the Article entity:
package net.bounceme.dur.usenet.model;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import net.bounceme.dur.usenet.controller.MessageBean;
#Entity
#Table(name = "articles", catalog = "nntp", schema = "")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Articles.findAll", query = "SELECT a FROM Article a"),
#NamedQuery(name = "Articles.findById", query = "SELECT a FROM Article a WHERE a.id = :id"),
#NamedQuery(name = "Articles.findByNumber", query = "SELECT a FROM Article a WHERE a.number = :number"),
#NamedQuery(name = "Articles.findBySent", query = "SELECT a FROM Article a WHERE a.sent = :sent")})
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id", nullable = false)
private Integer id;
#Basic(optional = false)
#Lob
#Column(name = "subject", nullable = false, length = 65535)
private String subject;
#Basic(optional = false)
#Lob
#Column(name = "content", nullable = false, length = 65535)
private String content;
#Basic(optional = false)
#Column(name = "number", nullable = false)
private int number;
#Basic(optional = false)
#Column(name = "sent", nullable = false)
#Temporal(TemporalType.DATE)
private Date sent;
#Basic(optional = false)
#Lob
#Column(name = "header_id_string", nullable = false, length = 65535)
private String headerIdString;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "newsgroupId")
private Collection<NewsgroupsArticles> newsgroupsArticlesCollection;
public Article() {
}
public Article(MessageBean messageBean) {
subject = messageBean.getSubject();
content = messageBean.getContent();
sent = messageBean.getSent();
number = messageBean.getNumber();
headerIdString = "dummy";
}
public Article(Integer id) {
this.id = id;
}
public Article(Integer id, String subject, String content, int number, Date sent, String headerIdString) {
this.id = id;
this.subject = subject;
this.content = content;
this.number = number;
this.sent = sent;
this.headerIdString = headerIdString;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Date getSent() {
return sent;
}
public void setSent(Date sent) {
this.sent = sent;
}
public String getHeaderIdString() {
return headerIdString;
}
public void setHeaderIdString(String headerIdString) {
this.headerIdString = headerIdString;
}
#XmlTransient
public Collection<NewsgroupsArticles> getNewsgroupsArticlesCollection() {
return newsgroupsArticlesCollection;
}
public void setNewsgroupsArticlesCollection(Collection<NewsgroupsArticles> newsgroupsArticlesCollection) {
this.newsgroupsArticlesCollection = newsgroupsArticlesCollection;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Article)) {
return false;
}
Article other = (Article) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "net.bounceme.dur.usenet.model.Articles[ id=" + id + " ]";
}
}
should that be built into the database and let inserts fail?
Absolutely, put it into the database.
It's your "last line of defense" and there is hardly a way around it. I you only have it your Java code you are not protected against faulty SQL scripts or programming errors.
You can still check in your code though e.g. to show the user a nicer error message.

Unsupported overload used for query operator 'Intersect'

I am able to do this query just fine with the test repository which is In Memory
when I move to the sqlRepository I get this error
Unsupported overload used for query operator 'Intersect'.
I assume it is because sending the query to sql is too complicated for Linq to Sql to do when it is not dealing with the Model.Model.Talent Type. Is there some way around doing a search like this with Intersect?
thanks
public class TalentService : ITalentService
{
ITalentRepository _repository = null;
private IQueryable<Talent> BasicSearch(string searchExpression)
{
IQueryable<Talent> t;
string[] sa = searchExpression.Trim().ToLower().Replace(" ", " ").Split(' ');
t = _repository.GetTalents();
foreach (string s in sa)
{
t = t.Intersect(AddBasicSearch(s), new TalentComparer());
}
return t;
}
private IQueryable<Talent> AddBasicSearch(string s)
{
IQueryable<Talent> t2 = _repository.GetTalents()
.Where(tal => tal.EyeColor.ToString().ToLower().Contains(s)
|| tal.FirstName.ToLower().Contains(s)
|| tal.LastName.ToLower().Contains(s)
|| tal.LanguagesString.ToLower().Contains(s)
);
return t2;
}
}
public class SqlTalentRepository:ITalentRepository
{
public IQueryable<Model.Model.Talent> GetTalents()
{
var tal = from t in _db.Talents
let tLanguage = GetTalentLanguages(t.TalentID)
where t.Active == true
select new Model.Model.Talent
{
Id = t.TalentID,
FirstName = t.FirstName,
LastName = t.LastName,
TalentLanguages = new LazyList<Model.Model.TalentLanguage>(tLanguage),
LanguagesString = t.TalentLanguages.ToLanguageNameString(_LanguageRepository.GetLanguages())
};
return tal ;
}
public IQueryable<Model.Model.TalentLanguage> GetTalentLanguages(int iTalentId)
{
var q = from y in this.talentLanguageList
let Languages = _LanguageRepository.GetLanguages()
where y.TalentId == iTalentId
select new Model.Model.TalentLanguage
{
TalentLanguageId = y.TalentLanguageId,
TalentId = y.TalentId,
LanguageId = y.LanguageId,
Language = Languages.Where(x => x.LanguageId == y.LanguageId).SingleOrDefault()
};
return q.AsQueryable<Model.Model.TalentLanguage>();
}
}
public static class TalentExtensions
{
public static string ToLanguageNameString(this IEnumerable<TalentLanguage> source
, IEnumerable<Model.Model.Language> allLanguages)
{
StringBuilder sb = new StringBuilder();
const string del = ", ";
foreach (TalentLanguage te in source)
{
sb.AppendFormat("{0}{1}", allLanguages
.Where(x => x.LanguageId == te.LanguageID).SingleOrDefault().LanguageName, del);
}
string sReturn = sb.ToString();
if (sReturn.EndsWith(del))
sReturn = sReturn.Substring(0, sReturn.Length - del.Length);
return sReturn;
}
}
public class TestTalentRepository : ITalentRepository
{
IList<Talent> talentList;
public TestTalentRepository(ILanguageRepository _LanguageRepo )
{
this._LanguageRepository = _LanguageRepo;
talentList = new List<Talent>();
talentLanguageList = new List<TalentLanguage>();
for (int i = 0; i < 55; i++)
{
var t = new Talent();
t.Id = i;
t.FirstName = (i % 3 == 0) ? "Ryan" : "Joe";
t.LastName = (i % 2 == 0) ? "Simpson" : "Zimmerman";
AddLanguagesToTestTalent(i, t);
talentList.Add(t);
}
}
private void AddLanguagesToTestTalent(int i, Talent t)
{
IList<Language> Languages = _LanguageRepository.GetLanguages().ToList<Language>();
Random rLanguages = new Random();
int numLanguages = rLanguages.Next(Languages.Count - 1) + 1;
t.TalentLanguages = new LazyList<TalentLanguage>();
for (int j = 0; j < numLanguages; j++)
{
var x = new TalentLanguage();
x.TalentLanguageId = j;
x.TalentId = i;
Random random2 = new Random();
int rand = random2.Next(Languages.Count);
var y = Languages.ElementAtOrDefault(rand);
Languages.RemoveAt(rand);
x.Language = y;
x.LanguageId = y.LanguageId;
t.TalentLanguages.Add(x);
}
}
public IQueryable<Talent> GetTalents()
{
var ts = from t in this.talentList
let tLanguage = GetTalentLanguages(t.Id)
where t.Active == true
select new Model.Model.Talent
{
Id = t.Id,
FirstName = t.FirstName,
LastName = t.LastName,
TalentLanguages = new LazyList<Model.Model.TalentLanguage>(tLanguage),
LanguagesString = t.TalentLanguages.ToLanguageNameString(_LanguageRepository.GetLanguages()),
City = t.City,
};
return ts.AsQueryable<Model.Model.Talent>();
}
public IQueryable<Model.Model.TalentLanguage> GetTalentLanguages(int iTalentId)
{
var q = from y in this.talentLanguageList
let Languages = _LanguageRepository.GetLanguages()
where y.TalentId == iTalentId
select new Model.Model.TalentLanguage
{
TalentLanguageId = y.TalentLanguageId,
TalentId = y.TalentId,
LanguageId = y.LanguageId,
Language = Languages.Where(x => x.LanguageId == y.LanguageId).SingleOrDefault()
};
return q.AsQueryable<Model.Model.TalentLanguage>();
}
}
If you're trying to find entries which match all of those criteria, you just need multiple where clauses:
private static readonly char[] SplitDelimiters = " ".ToCharArray();
private IQueryable<Talent> BasicSearch(string search)
{
// Just replacing " " with " " wouldn't help with "a b"
string[] terms = search.Trim()
.ToLower()
.Split(SplitDelimiters,
StringSplitOptions.RemoveEmptyEntries);
IQueryable<Talent> query = _repository.GetTalents();
foreach (string searchTerm in terms)
{
query = AddBasicSearch(query, searchTerm);
}
return query;
}
private IQueryable<Talent> AddBasicSearch(IQueryable<Talent> query, string s)
{
return query.Where(tal =>
tal.EyeColor.ToString().ToLower().Contains(s)
|| tal.FirstName.ToLower().Contains(s)
|| tal.LastName.ToLower().Contains(s)
|| tal.LanguagesString.ToLower().Contains(s)
);
}