这种方法从Spark 3.2.x
到Spark 3.3.x
都运行良好,
public Dataset<Commune> obtenirCommunes(SparkSession session, int anneeCOG) throws TechniqueException {
Dataset<Row> communes = rowCommunes(session, anneeCOG);
return communes
.select(communes.col("typeCommune"), communes.col("codeCommune"), communes.col("codeRegion"), communes.col("codeDepartement"),
communes.col("arrondissement"), communes.col("typeNomEtCharniere"), communes.col("nomMajuscules"), communes.col("nomCommune"),
communes.col("codeCanton"), communes.col("codeCommuneParente"), communes.col("sirenCommune"), communes.col("populationTotale").alias("population"),
communes.col("strateCommune"), communes.col("codeEPCI"), communes.col("surface"), communes.col("longitude"), communes.col("latitude"),
communes.col("nomDepartement"), communes.col("nomEPCI"))
.as(Encoders.bean(Commune.class))
.cache();
}
现在Spark 3.4.0
失败了,通过这个测试:
/**
* Charger le Code Officiel Géographique entier.
* @throws CommuneInexistanteException si la commune recherchée n'existe pas.
* @throws TechniqueException si un incident survient.
*/
@Test
@DisplayName("Lecture du code officiel géographique")
void cog() throws TechniqueException, CommuneInexistanteException {
for(int cog = COG_START; cog <= COG_END; cog ++) {
if (this.toutesAnnees == false && cog != COG_END) {
continue;
}
CodeOfficielGeographique maillage = this.cogDataset.obtenirCodeOfficielGeographique(this.session, cog, true);
LOGGER.info("Code Officiel Géographique : {} communes, {} intercommunalités.", maillage.getCommunes().size(), maillage.getIntercommunalites().size());
Intercommunalite intercommunalite = maillage.getIntercommunalites().values().iterator().next();
LOGGER.info("La première intercommunalité : {}", intercommunalite);
Commune cambremer = maillage.getCommune("14126");
assertNotNull(cambremer, MessageFormat.format("Cambremer aurait dû être trouvé dans le COG {0}.", cog));
LOGGER.info(cambremer.toString());
}
}
失败伴随着一个不太清楚的日志(它是调用失败的CogDataset:obtenirCommunes
的行CodeOfficielGeographique maillage = this.cogDataset.obtenirCodeOfficielGeographique(this.session, cog, true)
):
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:627)
at scala.None$.get(Option.scala:626)
at org.apache.spark.sql.catalyst.ScalaReflection$.$anonfun$deserializerFor$8(ScalaReflection.scala:359)
at scala.collection.immutable.ArraySeq.map(ArraySeq.scala:75)
at scala.collection.immutable.ArraySeq.map(ArraySeq.scala:35)
at org.apache.spark.sql.catalyst.ScalaReflection$.deserializerFor(ScalaReflection.scala:348)
at org.apache.spark.sql.catalyst.ScalaReflection$.deserializerFor(ScalaReflection.scala:183)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$.apply(ExpressionEncoder.scala:56)
at org.apache.spark.sql.catalyst.encoders.ExpressionEncoder$.javaBean(ExpressionEncoder.scala:62)
at org.apache.spark.sql.Encoders$.bean(Encoders.scala:179)
at org.apache.spark.sql.Encoders.bean(Encoders.scala)
at fr.ecoemploi.spark.dataset.cog.CogDataset.obtenirCommunes(CogDataset.java:220)
at fr.ecoemploi.spark.dataset.cog.CogDataset.obtenirCodeOfficielGeographique(CogDataset.java:186)
at fr.ecoemploi.spark.dataset.cog.CommuneObjectsMetiersIT.cog(CommuneObjectsMetiersIT.java:92)
Encoders.bean
的目标对象Commune
是这样的:
package fr.ecoemploi.metier.territoire;
import static fr.ecoemploi.metier.territoire.PrefixageNomCommune.*;
import java.io.Serial;
import java.text.*;
import java.util.*;
import java.util.function.Predicate;
import javax.validation.constraints.*;
import org.apache.commons.lang3.*;
import fr.fondation.utilitaires.autocontrole.*;
import fr.fondation.utilitaires.localisation.*;
import io.swagger.v3.oas.annotations.*;
import io.swagger.v3.oas.annotations.media.*;
/**
* Une commune.
* @author Marc LE BIHAN.
*/
@Schema(description = "Une commune du Code Officiel Géographique")
public class Commune extends ObjetMetierSpark {
/** Serial ID */
@Serial
private static final long serialVersionUID = 4381577514414536917L;
/** Collator utilisé pour comparer les noms de communes, sans accents. */
private static final Collator collator = Collator.getInstance(Locale.FRENCH);
static {
collator.setStrength(Collator.PRIMARY);
}
/** Code de la commune. */
@NotNull @Size(min = 5, max = 5) @Schema(description = "Code de la commune", example = "29019")
private String codeCommune;
/** Code ddépartement. */
@NotNull @Size(min=2, max=3) @Schema(description = "Code du département", example = "972")
private String codeDepartement;
/** Nom du département. */
@NotNull @Schema(description = "Nom du département", example = "Finistère")
private String nomDepartement;
/** Code de la commune parente (pour arrondissements, communes associées ou déléguées). */
@Size(min = 9, max = 9) @Schema(description = "Code de la commune parente", example = "75056", nullable = true)
private String codeCommuneParente;
/** Code INSEE de la région auquel appartient ce département. */
@NotNull @Size(min = 2, max = 2) @Schema(description = "Code de la région", example = "84")
private String codeRegion;
/** Code Canton de la commune. */
@Schema(description = "Code du canton", nullable = true)
private String codeCanton;
/** Nom de la ville. */
@NotNull @Schema(description = "Nom de la commune", example = "Brest")
private String nomCommune;
/** Nom en majuscule. */
@NotNull @Schema(description = "Nom de la commune en majuscules", example = "BREST")
private String nomMajuscules;
/** Type et nom charnière. */
@NotNull @Size(min=1, max=1)
@Schema(description = "Type de nom et charnière: <ul>"
+ "<li>0 Pas d'article et le nom commence par une consonne sauf H muet charnière = DE</li>"
+ "<li>1 Pas d'article et le nom commence par une voyelle ou un H muet charnière = D'</li>"
+ "<li>2 Article = LE charnière = DU</li>"
+ "<li>3 Article = LA charnière = DE LA</li>"
+ "<li>4 Article = LES charnière = DES</li>"
+ "<li>5 Article = L' charnière = DE L'</li>"
+ "<li>6 Article = AUX charnière = DES</li>"
+ "<li>7 Article = LAS charnière = DE LAS</li>"
+ "<li>8 Article = LOS charnière = DE LOS</li>"
+ "</ul>")
private String typeNomEtCharniere;
/** SIREN de la commune (permet de la lier à son intercommunalité). */
@NotNull @Size(min=9, max=9) @Schema(description = "Numéro SIREN de la commune", example = "212900195")
private String sirenCommune;
/** Liste des groupements dont cette commune est le siège. */
@NotNull
@Schema(description = "Liste des groupements (EPCI, ultérieurement : syndicats) dont cette commune est le siège. "
+ "Cette liste est vide si la commune n'est siège d'aucun syndicat ou intercommunalité.", example = "[242900314]")
private Set<String> siegeGroupements = new HashSet<>();
/** Liste des intercommunalités dont cette commune est membre. */
@NotNull @Schema(description = "Liste des groupepements (EPCI, ultérieurement : syndicats) dont cette commune est membre.", example = "[242900314]")
private Set<String> membreGroupements = new HashSet<>();
/** Intercommunalité à fiscalité propre à laquelle cette commune appartient (qu'elle en soit siège ou membre). */
@NotNull @Size(min=9, max=9) @Schema(description = "Numéro SIREN de l'intercommunalité dont cette commune est siège ou membre.", example = "242900314")
private String epciFiscalitePropre;
/** Nom de de l'intercommunalité à laquelle la commune appartient. */
@NotNull @Schema(description = "Nom de l'intercommunalité à laquelle la commune appartient", example = "Brest Métropole")
private String nomEPCI;
/** Arrondissement de la commune. */
@Schema(description = "Code de l'arrondissement de la commune.", nullable = true)
private String arrondissement;
/** Population de la commune. */
@NotNull @Schema(description = "Population totale de la commune.")
private Integer population;
/** Type de la commune. */
@NotNull
@Schema(description = "Type de la commune : <ul>" +
"<li>COM Commune</li>" +
"<li>COMA Commune associée</li>" +
"<li>COMD Commune déléguée</li>" +
"<li>ARM Arrondissement municipal</li>"
+ "</ul>", example = "COM")
private String typeCommune;
/** Strate communale. */
@NotNull
@Schema(description = "Strate communale : <ul>" +
"<li>1 : Moins de 100 habitants</li>" +
"<li>2 : De 100 à moins de 200 habitants</li>" +
"<li>3 : De 200 à moins de 500 habitants</li>" +
"<li>4 : De 500 à moins de 2 000 habitants</li>" +
"<li>5 : De 2 000 à moins de 3 500 habitants</li>" +
"<li>6 : De 3 500 à moins de 5 000 habitants</li>" +
"<li>7 : De 5 000 à moins de 10 000 habitants</li>" +
"<li>8 : de 10 000 à moins de 20 000 habitants</li>" +
"<li>9 : de 20 000 à moins de 50 000 habitants</li>" +
"<li>10 : de 50 000 à moins de 100 000 habitants</li>" +
"<li>11 : 100 000 habitants et plus</li>" +
"</ul>", example = "1")
private Integer strateCommune;
/** Surface de la commune en hectares. */
@Schema(description = "Surface de la commune, en hectares. N'est pas alimenté pour les arrondissements.", example = "1520.25", nullable = true)
private Double surface;
/** Longitude du centroïde de la commune. */
@Schema(description = "Longitude du centroïde de la commune. N'est pas alimenté pour les arrondissements.", example = "-4.2908", nullable = true)
private Double longitude;
/** Latitude du centroïde de la commune. */
@Schema(description = "Latitude du centroïde de la commune. N'est pas alimenté pour les arrondissements.", example = "48.2327", nullable = true)
private Double latitude;
/**
* Construire une commune.
*/
public Commune() {
}
/**
* Ajouter une intercommunalité dont cette commune est membre.
* @param sirenIntercommunalite SIREN de l'intercommunalité.
*/
public void ajouterMembreGroupement(String sirenIntercommunalite) {
this.membreGroupements.add(sirenIntercommunalite);
}
/**
* Ajouter une intercommunalité dont cette commune est le siège.
* @param sirenIntercommunalite SIREN de l'intercommunalité.
*/
public void ajouterSiegeGroupement(String sirenIntercommunalite) {
this.siegeGroupements.add(sirenIntercommunalite);
}
/**
* Renvoyer le code Canton de la commune.
* @return Code canton de la commune.
*/
public String getCodeCanton() {
return this.codeCanton;
}
/**
* Fixer le code canton de la commune.
* @param codeCanton Code canton de la commune.
*/
public void setCodeCanton(String codeCanton) {
this.codeCanton = codeCanton;
}
/**
* Renvoyer le code de la commune.
* @return Code de la commune.
*/
public String getCodeCommune() {
return this.codeCommune;
}
/**
* Renvoyer le code de la commune.
* @return Code de la commune.
*/
public CodeCommune astCodeCommune() {
return new CodeCommune(this.codeCommune);
}
/**
* Renvoyer le code commune parente (pour arrondissements, communes associées ou déléguées).
* @return Code commune parente.
*/
public CodeCommune astCodeCommuneParente() {
return new CodeCommune(this.codeCommuneParente);
}
/**
* Renvoyer le code commune parente (pour arrondissements, communes associées ou déléguées).
* @return Code commune parente.
*/
public String getCodeCommuneParente() {
return this.codeCommuneParente;
}
/**
* Renvoyer le code département.
* @return Code département.
*/
public CodeDepartement asCodeDepartement() {
return new CodeDepartement(this.codeDepartement);
}
/**
* Renvoyer le code département.
* @return Code département.
*/
public String getCodeDepartement() {
return this.codeDepartement;
}
/**
* Renvoyer le code région.
* @return Code région.
*/
public CodeRegion asCodeRegion() {
return new CodeRegion(this.codeRegion);
}
/**
* Renvoyer le code région.
* @return Code région.
*/
public String getCodeRegion() {
return this.codeRegion;
}
/**
* Renvoyer l'intercommunalité à fiscalité propre à laquelle cette commune appartient, qu'elle en soit siège ou membre.
* @return Intercommunalité.
*/
public SIREN asEpciFiscalitePropre() {
return new SIREN(this.epciFiscalitePropre);
}
/**
* Renvoyer l'intercommunalité à fiscalité propre à laquelle cette commune appartient, qu'elle en soit siège ou membre.
* @return Intercommunalité.
*/
@Hidden
public String getCodeEPCI() {
return this.epciFiscalitePropre;
}
/**
* Fixer l'intercommunalité à fiscalité propre à laquelle cette commune appartient, qu'elle en soit siège ou membre.
* @param epci Intercommunalité.
*/
@Hidden
public void setCodeEPCI(String epci) {
this.epciFiscalitePropre = epci;
}
/**
* Renvoyer les groupements dont cette commune est membre.
* @return Groupements.
*/
public Set<String> membreGroupements() {
return this.membreGroupements;
}
/**
* Renvoyer la liste des groupements dont cette commune est le siège.
* @return liste des groupements.
*/
public Set<String> siegeGroupements() {
return this.siegeGroupements;
}
/**
* Renvoyer l'arrondissement.
* @return Arrondissement.
*/
public String getArrondissement() {
return this.arrondissement;
}
/**
* Déterminer si ce code commune désigne une collectivité d'outre-mer :<br>
* Attention, il s'agit des départements 975, 977, 978 et 98, et pas les départements d'outremer 971, 972, 973, 974 et 976.
* @return true si c'est le cas.
*/
@Hidden
public boolean isCollectiviteOutremer() {
return this.codeCommune != null &&
(this.codeCommune.startsWith("975") || this.codeCommune.startsWith("977") || this.codeCommune.startsWith("978") || this.codeCommune.startsWith("98"));
}
/**
* Fixer l'arrondissement.
* @param arrondissement Arrondissement.
*/
public void setArrondissement(String arrondissement) {
this.arrondissement = arrondissement;
}
/**
* Renvoyer le nom de la commune.
* @return Nom de la commune.
*/
public String getNomCommune() {
return this.nomCommune;
}
/**
* Déterminer si notre commune a le même nom que celle en paramètre.
* @param nomCandidat Nom de commune : il peut contenir une charnière.
* @return true si c'est le cas.
*/
public boolean hasMemeNom(String nomCandidat) {
// Si le nom soumis vaut null, répondre non.
if (nomCandidat == null) {
return false;
}
// Faire une comparaison directe de nom de commune tout d'abord, car l'emploi du collator est très coûteux.
if (nomCandidat.equalsIgnoreCase(this.nomCommune)) {
return true;
}
// Puis, rechercher avec les différentes charnières.
if (nomCandidat.equalsIgnoreCase(nomAvecType(false, PrefixageNomCommune.AUCUN))) {
return true;
}
if (nomCandidat.equalsIgnoreCase(nomAvecType(false, PrefixageNomCommune.A))) {
return true;
}
if (nomCandidat.equalsIgnoreCase(nomAvecType(false, PrefixageNomCommune.POUR))) {
return true;
}
// En cas d'échec, reprendre ces tests, mais avec le collator, plus lent, mais qui passera outre les caractères accentués.
if (collator.equals(nomCandidat, this.nomCommune)) {
return true;
}
if (collator.equals(nomCandidat, nomAvecType(false, PrefixageNomCommune.AUCUN))) {
return true;
}
if (collator.equals(nomCandidat, nomAvecType(false, PrefixageNomCommune.A))) {
return true;
}
if (collator.equals(nomCandidat, nomAvecType(false, PrefixageNomCommune.POUR))) {
return true;
}
// Alternative aux tests précédents
List<Predicate<String>> memeNoms = new ArrayList<>();
memeNoms.add(nom -> nom.equalsIgnoreCase(nomAvecType(false, PrefixageNomCommune.AUCUN)));
memeNoms.add(nom -> nom.equalsIgnoreCase(nomAvecType(false, PrefixageNomCommune.A)));
memeNoms.add(nom -> nom.equalsIgnoreCase(nomAvecType(false, PrefixageNomCommune.POUR)));
memeNoms.add(nom -> collator.equals(nom, this.nomCommune));
memeNoms.add(nom -> collator.equals(nom, nomAvecType(false, PrefixageNomCommune.AUCUN)));
memeNoms.add(nom -> collator.equals(nom, nomAvecType(false, PrefixageNomCommune.A)));
memeNoms.add(nom -> collator.equals(nom, nomAvecType(false, PrefixageNomCommune.POUR)));
return memeNoms.stream().anyMatch(memeNom -> memeNom.test(nomCandidat));
}
/**
* Renvoyer le nom de la commune avec sa charnière accolée : Ville D'Ermenouville, Ville de Villenoy
* @param majuscules true S'il faut que la ville et sa charnière soient en majuscules.
* @return Nom de la commune avec sa charnière.
*/
public String nomAvecCharniere(boolean majuscules) {
String articleCommune = switch(asArticleEtCharniere()) {
case AUCUN_D_APOSTROPHE -> "d'";
case AUX_DES, LES_DES -> "des ";
case LAS_DE_LAS -> "de las ";
case LA_DE_LA -> "de la ";
case LE_DU -> "du ";
case LOS_DE_LOS -> "de los ";
case L_APOSTROPHE_DE_L_APOSTROPHE -> "l'";
default -> // inclut le cas : AUCUN_CONSONNE_DE
"de ";
};
String texte = articleCommune + (majuscules ? this.nomMajuscules : this.nomCommune);
return majuscules ? texte.toUpperCase(Locale.FRENCH) : texte;
}
/**
* Renvoyer le nom de la commune avec son type accolé : Bienvenue à Ermenouville, Bienvenue aux Ullis.
* @param majuscules true S'il faut que la ville et sa charnière soient en majuscules.
* @param prefixage Indique s'il faut replacer type vide par 'à', 'pour' : "Bienvenue à St-Etienne", "pour les Ullis".
* @return Nom de la commune avec sa charnière.
*/
public String nomAvecType(boolean majuscules, PrefixageNomCommune prefixage) {
String articleCommune = "";
String prefixe = "";
final String PREFIXE_POUR = "pour ";
switch(asArticleEtCharniere()) {
case AUCUN_CONSONNE_DE -> {
if (prefixage.equals(A))
articleCommune = "à ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case AUCUN_D_APOSTROPHE -> {
if (prefixage.equals(A))
prefixe = "à ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case AUX_DES -> articleCommune = "aux ";
case LAS_DE_LAS -> {
articleCommune = "las ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case LA_DE_LA -> {
articleCommune = "la ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case LES_DES -> {
articleCommune = "les ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case LE_DU -> {
articleCommune = "le ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case LOS_DE_LOS -> {
articleCommune = "los ";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
case L_APOSTROPHE_DE_L_APOSTROPHE -> {
articleCommune = "l'";
if (prefixage.equals(POUR))
prefixe = PREFIXE_POUR;
}
default -> {
if (prefixage.equals(A))
prefixe = "à ";
}
}
String texte = prefixe + articleCommune + (majuscules ? this.nomMajuscules : this.nomCommune);
return majuscules ? texte.toUpperCase(Locale.FRENCH) : texte;
}
/**
* Renvoyer le nom de la commune en majuscules.
* @return Nom de la commune.
*/
public String getNomMajuscules() {
return this.nomMajuscules;
}
/**
* Obtenir la population de la commune une année particulière.
* @return population de la commune.
*/
public Integer getPopulation() {
return this.population;
}
/**
* Convertit un type de nom INSEE en enum charnière INSEE.
* @return Enumération.
*/
public ArticleEtCharniereINSEE asArticleEtCharniere() {
for(ArticleEtCharniereINSEE candidat : ArticleEtCharniereINSEE.values()) {
if (candidat.getCode().equals(this.typeNomEtCharniere))
return candidat;
}
return null;
}
/**
* Renvoyer l'article et la charnière.
* @return Article et charnière.
*/
public String getTypeNomEtCharniere() {
return this.typeNomEtCharniere;
}
/**
* Déterminer si la commune a un numéro de SIREN alimenté
* (elle en a forcément un, mais parfois l'objet métier ne le porte pas encore).
* @return true, si c'est le cas.
*/
public boolean hasSIREN() {
return this.sirenCommune != null && StringUtils.isBlank(this.sirenCommune) == false;
}
/**
* Fixer le code de la commune.
* @param code Code de la commune.
*/
public void setCodeCommune(String code) {
this.codeCommune = code;
}
/**
* Fixer le code de la commune parente (pour arrondissements, communes associées ou déléguées).
* @param code Code de la commune parente (pour arrondissements, communes associées ou déléguées).
*/
public void setCodeCommuneParente(String code) {
this.codeCommuneParente = code;
}
/**
* Fixer le code département.
* @param code Code département.
*/
public void setCodeDepartement(String code) {
this.codeDepartement = code;
}
/**
* Fixer le code région.
* @param code Code région.
*/
public void setCodeRegion(String code) {
this.codeRegion = code;
}
/**
* Fixer les groupements dont cette commune est membre.
* @param groupements Groupements.
*/
public void membreGroupements(Set<String> groupements) {
this.membreGroupements = groupements;
}
/**
* Fixer les groupements dont cette commune est le siège.
* @param siegeIntercommunalites Intercommunalités.
*/
public void siegeGroupements(Set<String> siegeIntercommunalites) {
this.siegeGroupements = siegeIntercommunalites;
}
/**
* Renvoyer la latitude de la commune.
* @return Latitude de la commune.
*/
public Double getLatitude() {
return this.latitude;
}
/**
* Fixer la latitude de la commune.
* @param latitude Latitude de la commune.
*/
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
/**
* Renvoyer la longitude de la commune.
* @return Longitude de la commune.
*/
public Double getLongitude() {
return this.longitude;
}
/**
* Fixer la longitude de la commune.
* @param longitude Longitude de la commune.
*/
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
/**
* Renvoyer le nom du département.
* @return Nom du département.
*/
public String getNomDepartement() {
return this.nomDepartement;
}
/**
* Fixer le nom du département.
* @param nomDepartement Nom du département.
*/
public void setNomDepartement(String nomDepartement) {
this.nomDepartement = nomDepartement;
}
/**
* Renvoyer le nom de l'EPCI dont la commune est membre ou siège.
* @return Nom de l'EPCI.
*/
public String getNomEPCI() {
return this.nomEPCI;
}
/**
* Fixer le nom de l'EPCI dont la commune est membre ou siège.
* @param nomEPCI Nom de l'EPCI.
*/
public void setNomEPCI(String nomEPCI) {
this.nomEPCI = nomEPCI;
}
/**
* Fixer le nom de la ville.
* @param nomVille Nom de la ville.
*/
public void setNomCommune(String nomVille) {
this.nomCommune = nomVille;
}
/**
* Fixer le nom de la commune en majuscules.
* @param nomVille Nom de la commune.
*/
public void setNomMajuscules(String nomVille) {
this.nomMajuscules = nomVille;
}
/**
* Fixer la population de la commune une année donnée.
* @param population Population.
*/
public void setPopulation(Integer population) {
this.population = population;
}
/**
* Renvoyer le SIREN de la commune.
* @return SIREN.
*/
public SIRENCommune asSiren() {
return new SIRENCommune(this.sirenCommune);
}
/**
* Renvoyer le SIREN de la commune.
* @return SIREN.
*/
public String getSirenCommune() {
return this.sirenCommune;
}
/**
* Fixer le code SIREN de la commune.
* @param sirenCommune Siren.
*/
public void setSirenCommune(String sirenCommune) {
this.sirenCommune = sirenCommune;
}
/**
* Renvoyer la strate communale.
* @return Strate :<br>
* 1 : Moins de 100 habitants<br>
* 2 : De 100 à moins de 200 habitants<br>
* 3 : De 200 à moins de 500 habitants<br>
* 4 : De 500 à moins de 2 000 habitants<br>
* 5 : De 2 000 à moins de 3 500 habitants<br>
* 6 : De 3 500 à moins de 5 000 habitants<br>
* 7 : De 5 000 à moins de 10 000 habitants<br>
* 8 : de 10 000 à moins de 20 000 habitants<br>
* 9 : de 20 000 à moins de 50 000 habitants<br>
* 10 : de 50 000 à moins de 100 000 habitants<br>
* 11 : 100 000 habitants et plus
*/
public Integer getStrateCommune() {
return this.strateCommune;
}
/**
* Fixer la strate communale.
* @param strate Strate communele.
*/
public void setStrateCommune(Integer strate) {
this.strateCommune = strate;
}
/**
* Renvoyer la surface de la commune, en hectares.
* @return Surface en hectares.
*/
public Double getSurface() {
return this.surface;
}
/**
* Fixer la surface de la communes, en hectares.
* @param surface Surface en hectares.
*/
public void setSurface(Double surface) {
this.surface = surface;
}
/**
* Fixer le type nom et charnière.
* @param type Type nom et charnière.
*/
public void setTypeNomEtCharniere(String type) {
this.typeNomEtCharniere = type;
}
/**
* Renvoyer le type de commune.
* @return Type de commune.
*/
public String getTypeCommune() {
return this.typeCommune;
}
/**
* Fixer le type de commune.
* @param typeDeCommune Type de commune.
*/
public void setTypeCommune(String typeDeCommune) {
this.typeCommune = typeDeCommune;
}
/**
* @see fr.fondation.objets.ObjetMetierIdentifiable#toString()
*/
@Override
public String toString() {
return BabelTower.format(Commune.class, "toString", this.nomCommune, this.nomMajuscules, this.codeDepartement, this.codeRegion,
this.codeCommuneParente, this.typeNomEtCharniere, this.codeCommune, this.sirenCommune, this.siegeGroupements,
this.membreGroupements, this.epciFiscalitePropre, this.arrondissement, this.codeCanton, this.population, this.strateCommune,
this.surface, this.longitude, this.latitude, this.nomDepartement, this.nomEPCI);
}
}
我的假设是,Encoders.bean
改变了它在3.4.0
中的工作方式,或者它的先决条件,但是我不知道它现在拒绝了什么。
1条答案
按热度按时间uxhixvfz1#
问题始于堆栈跟踪中的
private def deserializerFor(enc: AgnosticEncoder[_], path: Expression, walkedTypePath: WalkedTypePath)
。它尝试运行这段代码:
在这里,在其搜索中,它搜索
isCollectiviteOutremer
方法,并找到:(or类似的东西,我在调试中解决了它)。重要的是,对于setter它有:
None
。因为它尝试编码的方法是:
这是一种实用的方法,不需要设置器。
实际上,这个方法不需要编码到字段中,但是我不知道如何告诉
Encoders.bean(...)
跳过它。如果存在注解,或者其他什么。无论如何,我能够通过将其返回类型从
boolean
更改为Boolean
来删除该编码尝试,然后我就不再有问题了:方法isCollectiviteOutremer
不再列在fields
中。然而,我对这个问题的回答更多的是一种变通方法,而不是一个好的解决方案。